diff --git a/ScenarioDemos/AstronautsGame/README_zh.md b/ScenarioDemos/AstronautsGame/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..0386bfd0053aa79979aa0b3b522e047f88c66363 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/README_zh.md @@ -0,0 +1,60 @@ + + +# 太空人避障游戏代码介绍 + +### 简介 +本Sample是基于OpenHarmony轻量级系统,利用内核的实时性和丰富的外设拓展功能,运行在Hi3861 WLAN模组上的应用游戏。 + + +### 使用说明 + +##### 1. 编译步骤 + +1)拷贝本Sample目录下的common、astronauts_game 文件夹到OpenHarmony 系统源码中的applications/sample/wifi-iot/app目录下。 + +2) 修改applications/sample/wifi-iot/app/BUILD.gn 文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,具体配置如下。 + +``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "astronauts_game", + ] + deps = [ "//applications/sample/wifi-iot/app/common/hals:hals" ] +} + +``` +3)修改hi3861 内核配置文件 + +​ 打开 device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk 文件 + +​ 将 CONFIG_I2C_SUPPORT is not set这一行, 改为CONFIG_I2C_SUPPORT=y + +​ 将 CONFIG_PWM_SUPPORT is not set这一行, 改为CONFIG_PWM_SUPPORT=y + +4) 代码编译和烧录请参考:[链接](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-connection.md) + +##### 2. 游戏玩法如下 + +1)上电后进入游戏初始界面,按下开发板中的user按键开始游戏。 + +2)使用OLED拓展板上的按键1、按键2左右移动来躲避随机落下的障碍物。 + +3) 屏幕右上角会记录得分,难度会随着分数的增加而提高。 + +4)如果碰撞到障碍物和OLED屏左右末端,则游戏结束。 + +5)按下user按键重新开始游戏。 + + + +### 约束限制 + +硬件:HiSpark Wi-Fi IoT 开发套件(本sample会用到 主控板、OLED拓展板、带蜂鸣器的拓展板) + +软件:OpenHarmony 2.0 Canary版本。[链接](https://device.harmonyos.com/cn/docs/start/get-code/sourcecode-acquire-0000001050769927) + +OpenHarmony轻量级开发指导:[链接](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-lite-overview-0000001105598722) + +开发工具下载:[链接](https://device.harmnyos.com/cn/ide) \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/BUILD.gn b/ScenarioDemos/AstronautsGame/astronauts_game/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..86bf041949b7380e91c2f0b1db71097f7899997c --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("astronauts_game") { + sources = [ + "src/game_logic.c", + "src/button.c", + "src/common_init.c", + "src/main.c", + "src/oled.c", + "src/music.c" + ] + + include_dirs = [ + "//utils/native/lite/include", + "//kernel/liteos_m/components/cmsis/2.0", + "//base/iot_hardware/peripheral/interfaces/kits", + "//applications/sample/wifi-iot/app/common/include", + "//applications/sample/wifi-iot/app/astronauts_game/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include" + ] +} diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/button.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/button.h new file mode 100755 index 0000000000000000000000000000000000000000..caa29eb9a6594c28612ba424acaef4c8b15d4fa8 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/button.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUTTON_H +#define BUTTON_H + +#include "ohos_types.h" + +typedef enum { + ADC_USR_MIN = 5, + ADC_USR_MAX = 228, + ADC_S1_MIN, + ADC_S1_MAX = 512, + ADC_S2_MIN, + ADC_S2_MAX = 854 +}AdcValue; + +typedef enum { + SSU_NONE, + SSU_USER, + SSU_S1, + SSU_S2 +}KeyCode; + +typedef void (*KeyEventCallback)(uint32 key); + +/** + * @brief Setting the param of button gpio. + * + * @since 1.0 + * @version 1.0 + */ +void ButtonInit(void); + +/** + * @brief Register the buttion interrupt. + * + * @param eventCall + * @since 1.0 + * @version 1.0 + */ +void RegButtonIrq(KeyEventCallback eventCall); +#endif // BUTTON_H diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/code_tab.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/code_tab.h new file mode 100755 index 0000000000000000000000000000000000000000..a81b6a20488c75cc7584b90959965291bb642905 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/code_tab.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CODE_TAB_H +#define CODE_TAB_H + +#include "ohos_types.h" + +const uint16 Font7x10 [] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +#endif // CODE_TAB_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/common_init.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/common_init.h new file mode 100755 index 0000000000000000000000000000000000000000..304db24ca0648d846a4aa96d55c95157840e2212 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/common_init.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_INIT_H +#define COMMON_INIT_H + +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "iot_i2c.h" + +/** + * @brief Init the device. Include the button 、Oled. + * + * @since 1.0 + * @version 1.0 + */ +void DeviceInit(void); + +#endif /* COMMON_INIT_H */ diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/game_logic.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/game_logic.h new file mode 100755 index 0000000000000000000000000000000000000000..af5cdc891d4062b0782751d24939254419e6db40 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/game_logic.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GAME_LOGIC_H +#define GAME_LOGIC_H + +#include "ohos_types.h" + +typedef enum { + OBSTACLE_1, + OBSTACLE_2, + OBSTACLE_3 +}OBSTACLE_ID; + +void GameStart(void); + +int GameLoop(void); + +void DrawGameScreen(void); + +void GameOver(void); + +void AstronautMove(uint32 flag); + +void RefreshGameDifficulty(void); +#endif // GAME_LOGIC_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/main.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/main.h new file mode 100755 index 0000000000000000000000000000000000000000..091e3fc14cddb71273e93b862dfd70550a2fabaa --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/main.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MAIN_H +#define MAIN_H + +#define OLED_MODE 0 +#define SIZE 8 +#define X_Level_L 0x00 +#define X_Level_H 0x10 +#define MAX_COLUMN 128 +#define MAX_ROW 64 +#define BRIGHTNESS 0xFF +#define X_WIDTH 128 +#define Y_WIDTH 64 +#define OLED_CMD 0 // 写命令 +#define OLED_DATA 1 // 写数据 + +#define DELAY_TIMES_OF_GAME_PENDING 300 +#define DELAY_TIMES_OF_GAME_SCRREN_REFLASH 100 +#define MAIN_TASK_STACK_SIZE (1024*10) +#define MOVE_LEFT 0 +#define MOVE_RIGHT 1 + +#endif // MAIN_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/music.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/music.h new file mode 100755 index 0000000000000000000000000000000000000000..79e8c4562a2b3e94e35fbc4508a3f03a5122d54a --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/music.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MUSIC_H +#define MUSIC_H + +void StartBeepMusicTask(void); + +void SetupMusicPlaybackFlag(bool flag); + +#endif // MUSIC_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/include/oled.h b/ScenarioDemos/AstronautsGame/astronauts_game/include/oled.h new file mode 100755 index 0000000000000000000000000000000000000000..7d852c422452f1410d7cca80667fb50da8e13e8d --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/include/oled.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OLED_H +#define OLED_H + +#include "ohos_types.h" + +#define SSD1306_I2C_ADDR (0x3C << 1) + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; +// Struct to store transformations + +typedef struct { + const uint8 FontWidth; /*!< Font width in pixels */ + uint8 FontHeight; /*!< Font height in pixels */ + const uint16 *data; /*!< Pointer to data font data array */ +} FontDef; + +typedef struct { + uint16 CurrentX; + uint16 CurrentY; + uint8 Inverted; + uint8 Initialized; + uint8 DisplayOn; +} SSD1306_t; + +typedef struct { + uint8 x; + uint8 y; +} SSD1306_VERTEX; + +void OledInit(void); + +void HAL_Delay(uint32 ms); +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8 x, uint8 y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char* str, uint32 size, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8 x, uint8 y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16 par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color); +void ssd1306_DrawArc(uint8 x, uint8 y, uint8 radius, uint16 start_angle, uint16 sweep, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8 par_x, uint8 par_y, uint8 par_r, SSD1306_COLOR color); +void ssd1306_DrawBitmap(const uint8* bitmap, uint32 size); +void ssd1306_DrawBitmapAtPosition(const uint8* bitmap, uint8 width, uint8 height, int8 xo, int8 yo); + +#endif // OLED_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/button.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/button.c new file mode 100755 index 0000000000000000000000000000000000000000..fa5740eb03fe0998deb0d23feeed65ade4b8d009 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/button.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cmsis_os2.h" +#include "button.h" +#include "common_log.h" +#include "peripheral_hal.h" + +#define BUTTON_TASK_STAK_SIZE (1024*4) +#define BUTTON_TASK_PRIORITY 24 +#define DELAY_200_MS 20 + +static KeyEventCallback g_buttonCallback = NULL; +void ButtonTask(void* arg) +{ + unsigned short data = 0; + int ret = SSU_NONE; + + while (1) { + if (HalAdcRead(HAL_WIFI_IOT_ADC_CHANNEL_2, &data, HAL_WIFI_IOT_ADC_EQU_MODEL_4, HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0) == 0) { + if ((ADC_USR_MIN <= data) && (data <= ADC_USR_MAX)) ret = SSU_USER; + if ((ADC_S1_MIN <= data) && (data <= ADC_S1_MAX)) ret = SSU_S1; + if ((ADC_S2_MIN <= data) && (data <= ADC_S2_MAX)) ret = SSU_S2; + } + if (ret != SSU_NONE) { + g_buttonCallback(ret); + ret = SSU_NONE; + } + osDelay(DELAY_200_MS); + } + return ret; +} + +void RegButtonIrq(KeyEventCallback buttonCallback) +{ + g_buttonCallback = buttonCallback; + osThreadAttr_t attr = {0}; + attr.name = (char*)"buttontask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = BUTTON_TASK_STAK_SIZE; + attr.priority = BUTTON_TASK_PRIORITY; + if (osThreadNew((osThreadFunc_t)ButtonTask, NULL, &attr) == NULL) { + LOG_E("Failed to create ControlSysTask !\n"); + } + return 0; +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/common_init.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/common_init.c new file mode 100755 index 0000000000000000000000000000000000000000..d35574ec78fa4b7e87e2efb2f8afee741a5bf791 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/common_init.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "button.h" +#include "common_init.h" +#include "oled.h" +#include "common_log.h" +#include "peripheral_hal.h" + +#define I2C_IDX_BAUDRATE (400000) +#define WIFI_IOT_OLED_I2C_IDX_0 0 +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 + +static void I2cBusInit(void) +{ + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_13); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); // Set up the gpio funcion as i2c + + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_14); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); + IoTI2cInit(WIFI_IOT_OLED_I2C_IDX_0, I2C_IDX_BAUDRATE); // Rate: 400kbps + LOG_I("I2C0 bus init success !\n"); +} + +void DeviceInit(void) +{ + I2cBusInit(); + OledInit(); + LOG_I("Device init success !\n"); +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/game_logic.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/game_logic.c new file mode 100755 index 0000000000000000000000000000000000000000..4e84b230557fcdef04a70c6ef33a0a89aa6007b6 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/game_logic.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "game_logic.h" +#include "oled.h" +#include "common_log.h" + +typedef struct obstacleAttr { + short X; + short Y; + short width; + short height; + _Bool Inverse; // 0 障碍物在 右半边,1 障碍物在 左半边 +} ObstacleAttr; + +static const unsigned char g_bitmapAstronauts[] = { + 0x07, 0xE0, 0x0C, 0x30, + 0x13, 0xC8, 0x24, 0x24, + 0x68, 0x16, 0x5F, 0xFA, + 0x50, 0x0A, 0x50, 0x0A, + 0x5F, 0xFA, 0x68, 0x16, + 0x24, 0x24, 0x13, 0xC8, + 0x3C, 0x3C, 0x77, 0xEE, + 0x51, 0x8A, 0x52, 0x4A, + 0x72, 0x4E, 0x51, 0x8A, + 0x70, 0x0E, 0x13, 0xC8, + 0x12, 0x48, 0x1E, 0x78, + 0x12, 0x48, 0x1E, 0x78 +}; + +static const unsigned char g_bitmapObstacle1[] = { + 0x00, 0x00, 0x00, 0x00, + 0x03, 0xC0, 0x03, 0xC0, + 0x07, 0xE0, 0x07, 0xE0, + 0x0F, 0xF0, 0x0F, 0xF0, + 0x1F, 0xF8, 0x1F, 0xF8, + 0x3F, 0xFC, 0x3F, 0xFC, + 0x7F, 0xFE, 0x7F, 0xFE, + 0x3F, 0xFC, 0x00, 0x00 +}; + +static const unsigned char g_bitmapObstacle2[] = { + 0x0F, 0xF0, 0x3F, 0xFC, + 0x7F, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xFE, + 0x3F, 0xFC, 0x0F, 0xF0 +}; + +static const unsigned char g_bitmapObstacle3[] = { + 0x07, 0xE0, 0x1F, 0xF8, + 0x3F, 0xFC, 0x7F, 0xFE, + 0x7F, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xFE, + 0x7F, 0xFE, 0x3F, 0xFC, + 0x1F, 0xF8, 0x07, 0xE0 +}; + +#define ASTRONAUTS_WIDTH 16 +#define ASTRONAUTS_HEIGHT 24 +#define ASTRONAUTS_DOWN_MARGIN 0 +#define OBSTACLE_INTERVAL 40 + +#define PIPES_COUNT 3 +#define ASTRONAUTS_INIT_POSITION_X 52 +#define ASTRONAUTS_INIT_POSITION_Y 40 +#define INIT_MOVE_SPEED_Y 1 +#define INIT_MOVE_SPEED_X 2 +#define OLED_WIDTH_DIVIDENDS 2 +#define X_POSITION_SHOW_GAME_OVER 10 +#define Y_POSITION_SHOW_GAME_OVER 20 +#define SPEED_LEVLE_1 1 +#define SPEED_LEVLE_2 2 +#define FLY_DISTANCE_TAG_1 50 +#define FLY_DISTANCE_TAG_2 200 + +static uint8 g_game_difficulty_flag = 0; +static uint8 g_isStarted = 0; +static short g_astronautsPositionX = ASTRONAUTS_INIT_POSITION_X; +static float g_moveSpeedY = INIT_MOVE_SPEED_Y; +static float g_moveSpeedX = INIT_MOVE_SPEED_X; +static uint32 g_flyDistance = 0; + +static ObstacleAttr g_obstacles[PIPES_COUNT]; + +static short g_obstacleParm [3][2] = { + {16, 16}, + {16, 8}, + {16, 14} +}; + +void SetRandPosition(ObstacleAttr *obstacle) +{ + if (obstacle->Inverse == 0) { + obstacle->X = (SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS + + rand() % ((SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS) - ASTRONAUTS_WIDTH)) - 1; + } else { + obstacle->X = (rand() % (SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS)) + 1; // 随机数对64取余 + } +} + +void GameInit(void) +{ + srand((unsigned)time(NULL)); // 用当前时间,设置种子 + for (short i = 0; i < PIPES_COUNT; i++) { + g_obstacles[i].Y = -(i * OBSTACLE_INTERVAL); + g_obstacles[i].Inverse = i % OLED_WIDTH_DIVIDENDS; // 0, 1, 0, 1, 左右 半个区域内 + g_obstacles[i].width = g_obstacleParm[i][0]; + g_obstacles[i].height = g_obstacleParm[i][1]; + SetRandPosition(&g_obstacles[i]); // 设置障碍物X轴上的随机位置 + } + g_astronautsPositionX = ASTRONAUTS_INIT_POSITION_X; // 太空人在X轴上的初始位置 + g_flyDistance = 0; // 飞行距离 +} + +void GenerateObstacle(ObstacleAttr *obstacle) +{ + obstacle->Y = -(OBSTACLE_INTERVAL * (PIPES_COUNT - 1)); // 起始地址为-120 + SetRandPosition(obstacle); +} + +void GameStart(void) +{ + GameInit(); + g_isStarted = 1; +} + +int IsCollision(void) +{ + if (g_astronautsPositionX < 0 || g_astronautsPositionX > SSD1306_WIDTH - ASTRONAUTS_WIDTH) return 1; // 碰触边界 + for (int i = 0; i < PIPES_COUNT; i++) { + if (((g_obstacles[i].Y) % SSD1306_WIDTH < SSD1306_HEIGHT) && // 在此条件下,才能发生碰撞 + ((g_obstacles[i].Y) % SSD1306_WIDTH > SSD1306_HEIGHT - ASTRONAUTS_HEIGHT - g_obstacles[i].height)) { + if ((g_astronautsPositionX > g_obstacles[i].X + g_obstacles[i].width) || + (g_astronautsPositionX < g_obstacles[i].X - ASTRONAUTS_WIDTH)) { // 非碰触情景 + return 0; + } else { + return 1; + } + } + } + return 0; +} + +void GameOver(void) +{ + g_isStarted = 0; + ssd1306_SetCursor(X_POSITION_SHOW_GAME_OVER, Y_POSITION_SHOW_GAME_OVER); + ssd1306_DrawString("== GAME OVER ==", sizeof("== GAME OVER =="), White); + ssd1306_UpdateScreen(); + g_moveSpeedY = INIT_MOVE_SPEED_Y; + g_moveSpeedX = INIT_MOVE_SPEED_X; +} + +void RefreshGameDifficulty(void) +{ + if (g_game_difficulty_flag != SPEED_LEVLE_1) { + if ((g_flyDistance > FLY_DISTANCE_TAG_1) && (g_flyDistance < FLY_DISTANCE_TAG_2)) { + g_game_difficulty_flag = SPEED_LEVLE_1; + g_moveSpeedY += SPEED_LEVLE_1; + g_moveSpeedX += SPEED_LEVLE_1; + } + } else if (g_game_difficulty_flag != SPEED_LEVLE_2) { + if (g_flyDistance > FLY_DISTANCE_TAG_2) { + g_game_difficulty_flag = SPEED_LEVLE_2; + g_moveSpeedY += SPEED_LEVLE_2; + g_moveSpeedX += SPEED_LEVLE_2; + } + } +} + +int GameLoop(void) +{ + if (g_isStarted) { + g_flyDistance += g_moveSpeedY; // 统计飞行总距离,用来计算得分 + for (short i = 0; i < PIPES_COUNT; i++) { + g_obstacles[i].Y += g_moveSpeedY; // 刷新障碍物的Y轴坐标 + if (g_obstacles[i].Y > SSD1306_HEIGHT) { + GenerateObstacle(&g_obstacles[i]); // 重新生成障碍参数 + } + } + + if (IsCollision()) { // 判断是否发生了碰撞 + LOG_I("=====Collision!!!======"); + return 1; + } else { + return 0; + } + } + return 0; +} + +void DrawObstacle(int x, ObstacleAttr obstacles) +{ + if (x > SSD1306_WIDTH) return; + + switch (x) { + case OBSTACLE_1: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle1, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + case OBSTACLE_2: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle2, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + case OBSTACLE_3: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle3, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + default: + break; + } +} + +void AstronautMove(uint32 flag) +{ + if (flag == 0) { + g_astronautsPositionX -= g_moveSpeedX; // move left + } else { + g_astronautsPositionX += g_moveSpeedX; // move right + } +} + +#define SCORE_CONVERSION_PARM 10 +#define SCORE_SHOW_PARM 30 +#define EDGE_OF_OLED_X 127 +#define EDGE_OF_OLED_Y 63 + +void DrawGameScreen(void) +{ + ssd1306_DrawBitmapAtPosition(g_bitmapAstronauts, ASTRONAUTS_WIDTH, + ASTRONAUTS_HEIGHT, g_astronautsPositionX, ASTRONAUTS_INIT_POSITION_Y); + for (short i = 0; i < PIPES_COUNT; i++) { + DrawObstacle(i, g_obstacles[i]); + } + + char buf[5]; + if (sprintf_s(buf, sizeof(buf), "%d", g_flyDistance / SCORE_CONVERSION_PARM) == -1) { + LOG_E("setting the game score failed !\n"); + } + ssd1306_SetCursor(SSD1306_WIDTH - SCORE_SHOW_PARM, 1); + ssd1306_DrawString(buf, sizeof(buf), White); + + ssd1306_DrawLine(0, 0, 0, EDGE_OF_OLED_Y, White); + ssd1306_DrawLine(EDGE_OF_OLED_X, 0, EDGE_OF_OLED_X, EDGE_OF_OLED_Y, White); + ssd1306_UpdateScreen(); +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/main.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/main.c new file mode 100755 index 0000000000000000000000000000000000000000..f614daaba6d2c6d0ca926902406ac3d323d1f7f7 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/main.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "stdio.h" +#include "ohos_init.h" +#include "cmsis_os2.h" + +#include "main.h" +#include "button.h" +#include "game_logic.h" +#include "common_init.h" +#include "common_log.h" +#include "oled.h" +#include "music.h" + +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_watchdog.h" +#include "iot_errno.h" +#include "peripheral_hal.h" + +static int g_gameRunningStatus = 0; + +void Button_Callback(uint32 event) +{ + LOG_I("[Button] Button_Callback() : %d\n", event); + if (event == SSU_S1) { + AstronautMove(MOVE_LEFT); // press S1, move left + } else if (event == SSU_S2) { + AstronautMove(MOVE_RIGHT); // press S2, move right + } else if (event == SSU_USER) { + g_gameRunningStatus = 1; // game start + } else { + LOG_I("The useless button_callback! \n"); + } +} + +void GameTask(void* arg) +{ + (void)arg; + IoTWatchDogDisable(); + DeviceInit(); + RegButtonIrq(Button_Callback); + StartBeepMusicTask(); + + while (!g_gameRunningStatus) { + HAL_Delay(DELAY_TIMES_OF_GAME_PENDING); // Waiting game start + } + + GameStart(); + SetupMusicPlaybackFlag(true); + while (1) { + int isCollision = GameLoop(); + RefreshGameDifficulty(); + + ssd1306_Fill(Black); + DrawGameScreen(); + HAL_Delay(DELAY_TIMES_OF_GAME_SCRREN_REFLASH); // Free system resources + + if (isCollision) { + SetupMusicPlaybackFlag(true); + GameOver(); + g_gameRunningStatus = 0; + + while (!g_gameRunningStatus) { + HAL_Delay(DELAY_TIMES_OF_GAME_PENDING); + } + GameStart(); + SetupMusicPlaybackFlag(true); + } + } +} + +void AstronautsAvoidObstaclesGame(void) +{ + osThreadAttr_t attr; + + attr.name = "GameTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = MAIN_TASK_STACK_SIZE; + attr.priority = osPriorityNormal; + + if (osThreadNew(GameTask, NULL, &attr) == NULL) { + LOG_E("[Game] Falied to create GameTask!\n"); + } +} + +SYS_RUN(AstronautsAvoidObstaclesGame); \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/music.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/music.c new file mode 100755 index 0000000000000000000000000000000000000000..66361dae3d39a5ba06ab9dfc90eb977a22eb106d --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/music.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "cmsis_os2.h" +#include "hi_pwm.h" +#include "common_log.h" + +#include "ohos_types.h" +#include "peripheral_hal.h" +#include "iot_gpio.h" +#include "iot_pwm.h" +#include "iot_errno.h" + +#define MUSIC_STACK_TASK_SIZE 1024 +#define WIFI_IOT_PWM_PORT_PWM0 0 +#define WIFI_IOT_IO_FUNC_GPIO_9_PWM0_OUT 5 +#define TIMES_OF_MUSICAL_NOTE_INTERVAL (125*1000) +#define THE_MULTIPLIER_OF_PWM_DUTY 0.5 +#define THE_TIMES_OF_RELEASE_CPU_RESOURCE (1000*1000) + +static bool music_playback_flag = false; + +static const uint16 g_tuneFreqs[] = { + 0, + 38223, // 1046.5 C + 34052, // 1174.7 D + 30338, // 1318.5 E + 28635, // 1396.9 F + 25511, // 1568 G + 22728, // 1760 A + 20249, // 1975.5 B + 19048 // Raise an octave of C +}; + +static const uint8 g_scoreNotes[] = { + 7, 4, 7, 4, +}; + +static const uint8 g_scoreDurations[] = { + 2, 2, 2, 2, +}; + +void PlaybackMusicSample(void) +{ + for (size_t i = 0; i < sizeof(g_scoreNotes) / sizeof(g_scoreNotes[0]); i++) { + uint32 tune = g_scoreNotes[i]; + uint16 freqDivisor = g_tuneFreqs[tune]; + uint32 tuneInterval = g_scoreDurations[i] * (TIMES_OF_MUSICAL_NOTE_INTERVAL); + HalPwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor * THE_MULTIPLIER_OF_PWM_DUTY, freqDivisor); // music playback + usleep(tuneInterval); + IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); // Turn off this tone play + } +} + +void SetupMusicPlaybackFlag(bool flag) +{ + music_playback_flag = flag; +} + +static void *BeeperMusicTask(const char *arg) +{ + (void)arg; + + LOG_D("BeeperMusicTask start!\r\n"); + hi_pwm_set_clock(PWM_CLK_XTAL); // Set the clock source as crystal clock 40Mhz + + while (1) { + if (music_playback_flag == true) { + PlaybackMusicSample(); + music_playback_flag = false; + } + usleep(THE_TIMES_OF_RELEASE_CPU_RESOURCE); + } + return NULL; +} + +void StartBeepMusicTask(void) +{ + osThreadAttr_t attr; + if (IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_9) != IOT_SUCCESS) { + LOG_E("GPIO%d Init Failed !\n", HAL_WIFI_IOT_IO_NAME_GPIO_9); + } + + if (HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_PWM0_OUT) != IOT_SUCCESS) { + LOG_E("GPIO%d Set Func failed !\n", HAL_WIFI_IOT_IO_NAME_GPIO_9); + } + + if (IoTPwmInit(WIFI_IOT_PWM_PORT_PWM0) != IOT_SUCCESS) { + LOG_E("PWM%d Init Failed !\n", WIFI_IOT_PWM_PORT_PWM0); + } + + attr.name = "BeeperMusicTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = MUSIC_STACK_TASK_SIZE; + attr.priority = osPriorityNormal; + + if (osThreadNew((osThreadFunc_t)BeeperMusicTask, NULL, &attr) == NULL) { + LOG_E("[LedExample] Falied to create BeeperMusicTask!\n"); + } +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/astronauts_game/src/oled.c b/ScenarioDemos/AstronautsGame/astronauts_game/src/oled.c new file mode 100755 index 0000000000000000000000000000000000000000..b777fa9c7e91da7b9452302cf65e458861621319 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/astronauts_game/src/oled.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cmsis_os2.h" +#include "ohos_types.h" +#include "code_tab.h" +#include "oled.h" +#include "common_log.h" +#include "iot_i2c.h" + +#define BITS_NAMBER 8 +#define SSD1306_I2C_IDX 0 +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1<<7) +#define TIME_CONVERSION_PARM 1000 +#define SSD1306_WRITEDATA_PARM 2 + +FontDef g_Font_7x10 = {7, 10, Font7x10}; + +// Screenbuffer +static uint8 SSD1306_Buffer[SSD1306_BUFFER_SIZE]; +// Screen object +static SSD1306_t SSD1306; + +void HAL_Delay(uint32 ms) +{ + const uint32 msPerTick = TIME_CONVERSION_PARM / osKernelGetTickFreq(); // 10ms + if (ms >= msPerTick) { + osDelay(ms / msPerTick); + } + + uint32 restMs = ms % msPerTick; + if (restMs > 0) { + usleep(restMs * TIME_CONVERSION_PARM); + } +} + +#define TIME_UNITS 1000 + +uint32 HAL_GetTick(void) +{ + const uint32 msPerTick = TIME_UNITS / osKernelGetTickFreq(); // 10ms + uint32 tickMs = osKernelGetTickCount() * msPerTick; + + uint32 csPerMs = osKernelGetSysTimerFreq() / TIME_UNITS; // 160K cycle/ms + uint32 csPerTick = csPerMs * msPerTick; // 1600K cycles/tick + uint32 restMs = osKernelGetSysTimerCount() % csPerTick / csPerMs; + + return tickMs + restMs; +} + +static uint32 ssd1306_SendData(uint8* data, size_t size) +{ + return IoTI2cWrite(SSD1306_I2C_IDX, SSD1306_I2C_ADDR, data, size); +} + +static uint32 ssd1306_WiteByte(uint8 regAddr, uint8 byte) +{ + uint8 buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8 byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +void ssd1306_WriteData(uint8* buffer, size_t buff_size) +{ + uint8 data[SSD1306_WIDTH * SSD1306_WRITEDATA_PARM] = {0}; + for (size_t i = 0; i < buff_size; i++) { + data[i *SSD1306_WRITEDATA_PARM] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * SSD1306_WRITEDATA_PARM + 1] = buffer[i]; + } + data[(buff_size - 1) * SSD1306_WRITEDATA_PARM] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +void ssd1306_SetDisplayOn(const uint8 on) +{ + uint8 value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +void ssd1306_SetContrast(const uint8 value) +{ + const uint8 kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_DrawPixel(uint8 x, uint8 y, SSD1306_COLOR color) +{ + if ((x >= SSD1306_WIDTH) || (y >= SSD1306_HEIGHT)) { + // Don't write outside the buffer + return; + } + + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color = (SSD1306_COLOR)!color; + } + + // Draw in the right color + if (color == White) { + SSD1306_Buffer[x + (y / BITS_NAMBER) * SSD1306_WIDTH] |= 1 << (y % BITS_NAMBER); + } else { + SSD1306_Buffer[x + (y / BITS_NAMBER) * SSD1306_WIDTH] &= ~(1 << (y % BITS_NAMBER)); + } +} + +#define ACSII_CODE_SPACE 32 +#define ACSII_RANGE_DEL 127 + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32 i, b, j; + + // Check if character is valid + if ((ch < ACSII_CODE_SPACE) || (ch > ACSII_RANGE_DEL - 1)) { return 0;} + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || + SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + return 0; + } + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ACSII_CODE_SPACE) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + return ch; +} + +char ssd1306_DrawString(char* str, uint32 size, SSD1306_COLOR color) +{ + // Write until null-byte + (void)size; + while (*str) { + if (ssd1306_DrawChar(*str, g_Font_7x10, color) != *str) { + // Char could not be written + return *str; + } + // Next char + str++; + } + + return *str; +} + +void ssd1306_DrawBitmapAtPosition(const uint8* bitmap, uint8 width, uint8 height, int8 xo, int8 yo) +{ + for (uint8 y = 0; y < height; y++) { + if (yo + y > SSD1306_HEIGHT || yo + y < 0) continue; + for (uint8 x = 0; x < width; x++) { + if (xo + x > SSD1306_WIDTH || xo + x < 0) continue; + uint8 byte = bitmap[(y * width / BITS_NAMBER) + (x / BITS_NAMBER)]; + uint8 bit = byte & (0x80 >> (x % BITS_NAMBER)); + ssd1306_DrawPixel(xo + x, yo + y, bit ? White : Black); + } + } +} + +// Position the cursor +void ssd1306_SetCursor(uint8 x, uint8 y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32 i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +#define DRAW_LINE_CALC_PARM 2 +void ssd1306_DrawLine(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color) +{ + int32 deltaX = abs(x2 - x1); + int32 deltaY = abs(y2 - y1); + int32 signX = ((x1 < x2) ? 1 : -1); + int32 signY = ((y1 < y2) ? 1 : -1); + int32 error = deltaX - deltaY; + + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + int32 error2 = error * DRAW_LINE_CALC_PARM; + if (error2 > -deltaY) { + error -= deltaY; + x1 += signX; + } + if (error2 < deltaX) { + error += deltaX; + y1 += signY; + } + } + return; +} + +#define CMD_SAVE_PARM 2 + +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + uint8 cmd[] = { + 0X21, // Set column start and end addresses + 0X00, // Column start address 0 + 0X7F, // Column end address 127 + 0X22, // Set page start and end addresses + 0X00, // Column start address 0 + 0X07, // Column end address 7 + }; + uint32 count = 0; + uint8 data[sizeof(cmd) * CMD_SAVE_PARM + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32 i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + if (memcpy_s(&data[count], sizeof(SSD1306_Buffer), SSD1306_Buffer, sizeof(SSD1306_Buffer)) != 0) { + LOG_E("Copy the SSD1306_Buffer failed.\n"); + } + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32 retval = ssd1306_SendData(data, count); + if (retval != OHOS_SUCCESS) { + LOG_E("ssd1306_UpdateScreen send frame data failed: %d!\r\n", retval); + } +} + +#define TIMES_FOR_VOLTAGE_STABLE 100 + +void ssd1306_Init(void) +{ + // Wait for the screen to boot + HAL_Delay(TIMES_FOR_VOLTAGE_STABLE); + + // Init OLED + ssd1306_SetDisplayOn(0); // display off + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + ssd1306_SetContrast(0xFF); + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK + ssd1306_WriteCommand(0xA6); // --set normal color + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK + ssd1306_WriteCommand(0x3F); // + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK + ssd1306_WriteCommand(0x12); + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel + + ssd1306_Fill(Black); // Clear screen + ssd1306_UpdateScreen(); // Flush buffer to screen + SSD1306.CurrentX = 0; // Set default values for screen object + SSD1306.CurrentY = 0; + SSD1306.Initialized = 1; +} + +#define SHOW_GAME_START_Y_1 10 +#define SHOW_GAME_START_Y_2 30 +#define OLED_VOLTAGE_STABLE_TIME 300 + +void OledInit(void) +{ + HAL_Delay(OLED_VOLTAGE_STABLE_TIME); + ssd1306_Init(); + ssd1306_Fill(Black); + ssd1306_SetCursor(0, SHOW_GAME_START_Y_1); + ssd1306_DrawString("== Game Start ==", sizeof("== Game Start =="), White); + ssd1306_SetCursor(0, SHOW_GAME_START_Y_2); + ssd1306_DrawString("Press button USER", sizeof("Press button USER"), White); + + uint32 start = HAL_GetTick(); + ssd1306_UpdateScreen(); + uint32 end = HAL_GetTick(); + LOG_I("ssd1306_UpdateScreen time cost: %d ms.\r\n", end - start); +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/hals/BUILD.gn b/ScenarioDemos/AstronautsGame/common/hals/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..fbd1f3af0b4116443be7893f2c005ab0e30639e8 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/hals/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("hals") { + sources = [ + "src/peripheral_hal.c", + "src/utils_hal.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include", + ] +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/hals/src/peripheral_hal.c b/ScenarioDemos/AstronautsGame/common/hals/src/peripheral_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..9b1d8dfefb467909c83131a9ecac2d84288d0ea2 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/hals/src/peripheral_hal.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "peripheral_hal.h" +#include "iot_errno.h" +#include "hi_io.h" +#include "hi_adc.h" +#include "hi_types_base.h" +#include "hi_watchdog.h" +#include "hi_pwm.h" + +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val) +{ + if (id == HAL_WIFI_IOT_IO_NAME_MAX) { + return IOT_FAILURE; + } + return hi_io_set_func((hi_io_name)id, val); +} + +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt) +{ + return hi_adc_read((hi_adc_channel_index)channel, (hi_u16*)data, (hi_adc_equ_model_sel)equModel, + (hi_adc_cur_bais)curBais, (hi_u16)rstCnt); +} + +void HalSetWatchDogEnable(int enable) +{ + if (enable == 0) { + hi_watchdog_disable(); + } else { + hi_watchdog_enable(); + } +} + +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq) +{ + return hi_pwm_start((hi_pwm_port)id, (hi_u16)duty, (hi_u16)freq); +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/hals/src/utils_hal.c b/ScenarioDemos/AstronautsGame/common/hals/src/utils_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..47e517ab98eb1079eeff7b5fad9d8be8b255ef50 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/hals/src/utils_hal.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos_types.h" +#include "hi_time.h" +#include "hi_types_base.h" +#include "utils_hal.h" + +void hal_udelay(uint32 us) +{ + hi_udelay((hi_u32)us); +} \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/include/common_log.h b/ScenarioDemos/AstronautsGame/common/include/common_log.h new file mode 100755 index 0000000000000000000000000000000000000000..2702154ebaca9847a03fd9ff14e1ad30f18ea49b --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/include/common_log.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __COMMON_LOG_H__ +#define __COMMON_LOG_H__ + +#include + +#define LOG_D(fmt, args...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_I(fmt, args...) printf("[INFO][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_E(fmt, args...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) + +#endif // __COMMON_LOG_H__ \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/include/network_manager_service.h b/ScenarioDemos/AstronautsGame/common/include/network_manager_service.h new file mode 100755 index 0000000000000000000000000000000000000000..ad4130219da25486733b125563ad097982516190 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/include/network_manager_service.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_MANAGER_SERVICE_H__ +#define __NETWORK_MANAGER_SERVICE_H__ + +typedef enum { + NET_EVENT_NULL, + NET_EVENT_CONFIG, // Config wifi + NET_EVENT_CONFIG_FAIL, // Config wifi failed + NET_EVENT_CONFIG_SUCC, // Config wifi success + NET_EVENT_CONNECTTING, // connectting wifi + NET_EVENT_CONN_FAILED, // connect wifi failed + NET_EVENT_CONNECTTED, // Wifi connected + NET_EVENT_DISTCONNECT, // Wifi disconnected + NET_EVENT_RECV_DATA, // Recv message from FA + + NET_EVENT_TYPE_NBR +}NET_EVENT_TYPE; + +typedef enum { + NET_MODE_IDLE, // the idle mode + NET_MODE_CONFIG, // the netcfg in the AP mode + NET_MODE_STA, // the netcfg int the STA mode + + NET_MODE_NBR +}NET_MODE_TYPE; + +typedef enum { + NET_STA_NULL, + NET_STA_CONFIG, // Config wifi + NET_STA_CONNECTTING, // connectting wifi + NET_STA_CONNECTTED, // Wifi connected + NET_STA_DISTCONNECT, // Wifi disconnected + + NET_STA_TYPE_NBR +}NET_STA_TYPE; + +/** + * @brief: the network config service callback + * + * @param event reference {@link NET_EVENT_TYPE} + * @param data The data of the event: NET_EVENT_RECV_DATA or NET_EVENT_SEND_DATA + * @since 1.0 + * @version 1.0 + */ +typedef int (*NetManagerEventCallback)(NET_EVENT_TYPE event, void *data); + +/** + * @brief Register the network config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The callback of netcfg module + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief Set the network mode. + * + * @param mode : the network module, reference {@NET_MODE_TYPE} + * @since 1.0 + * @version 1.0 + */ +void NetManagerSetNetMode(int mode); + +/** + * @brief Send msg to FA. + * + * @param msg : the msg to send + * @since 1.0 + * @version 1.0 + * + * @return 0 -- success, others -- failed + */ +int NetManagerSendMsg(const char *msg); + +/** + * @brief UnRegister the network config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetManagerDeinit(void); + +#endif // __NETWORK_MANAGER_SERVICE_H__ \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/include/peripheral_hal.h b/ScenarioDemos/AstronautsGame/common/include/peripheral_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..7bc596b0e7dc2d452844deb0d0aeba4b20fc2a62 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/include/peripheral_hal.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERIPHERAL_HAL_H +#define PERIPHERAL_HAL_H + +#include "ohos_types.h" + +/* gpio start */ +typedef enum { + /** GPIO hardware pin 0 */ + HAL_WIFI_IOT_IO_NAME_GPIO_0, + /** GPIO hardware pin 1 */ + HAL_WIFI_IOT_IO_NAME_GPIO_1, + /** GPIO hardware pin 2 */ + HAL_WIFI_IOT_IO_NAME_GPIO_2, + /** GPIO hardware pin 3 */ + HAL_WIFI_IOT_IO_NAME_GPIO_3, + /** GPIO hardware pin 4 */ + HAL_WIFI_IOT_IO_NAME_GPIO_4, + /** GPIO hardware pin 5 */ + HAL_WIFI_IOT_IO_NAME_GPIO_5, + /** GPIO hardware pin 6 */ + HAL_WIFI_IOT_IO_NAME_GPIO_6, + /** GPIO hardware pin 7 */ + HAL_WIFI_IOT_IO_NAME_GPIO_7, + /** GPIO hardware pin 8 */ + HAL_WIFI_IOT_IO_NAME_GPIO_8, + /** GPIO hardware pin 9 */ + HAL_WIFI_IOT_IO_NAME_GPIO_9, + /** GPIO hardware pin 10 */ + HAL_WIFI_IOT_IO_NAME_GPIO_10, + /** GPIO hardware pin 11 */ + HAL_WIFI_IOT_IO_NAME_GPIO_11, + /** GPIO hardware pin 12 */ + HAL_WIFI_IOT_IO_NAME_GPIO_12, + /** GPIO hardware pin 13 */ + HAL_WIFI_IOT_IO_NAME_GPIO_13, + /** GPIO hardware pin 14 */ + HAL_WIFI_IOT_IO_NAME_GPIO_14, + /** Maximum value */ + HAL_WIFI_IOT_IO_NAME_MAX, +} HalWifiIotIoName; + +/** + * @brief set IO function. + * + * @param id -- IO number, reference {@ HalWifiIotIoName}. + * @param val -- the io function value which defined in {@ hi_io.h}. + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val); +/* gpio end */ + + +/* adc start */ + +/** + * @brief Enumerates ADC channel indexes. + * + */ +typedef enum { + /** Channel 0 */ + HAL_WIFI_IOT_ADC_CHANNEL_0, + /** Channel 1 */ + HAL_WIFI_IOT_ADC_CHANNEL_1, + /** Channel 2 */ + HAL_WIFI_IOT_ADC_CHANNEL_2, + /** Channel 3 */ + HAL_WIFI_IOT_ADC_CHANNEL_3, + /** Channel 4 */ + HAL_WIFI_IOT_ADC_CHANNEL_4, + /** Channel 5 */ + HAL_WIFI_IOT_ADC_CHANNEL_5, + /** Channel 6 */ + HAL_WIFI_IOT_ADC_CHANNEL_6, + /** Channel 7 */ + HAL_WIFI_IOT_ADC_CHANNEL_7, + /** Button value */ + HAL_WIFI_IOT_ADC_CHANNEL_BUTT, +} HalWifiIotAdcChannelIndex; + +/** + * @brief Enumerates analog power control modes. + */ +typedef enum { + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_AUTO, + /** Manual control (AVDD = 1.8 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_1P8V, + /** Manual control (AVDD = 3.3 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_3P3V, + /** Button value */ + HAL_WIFI_IOT_ADC_CUR_BAIS_BUTT, +} HalWifiIotAdcCurBais; + +/** + * @brief Enumerates equation models. + */ +typedef enum { + /** One-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_1, + /** Two-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_2, + /** Four-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_4, + /** Eight-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_8, + /** Button value */ + HAL_WIFI_IOT_ADC_EQU_MODEL_BUTT, +} HalWifiIotAdcEquModelSel; + +/** + * @brief Reads a piece of sampled data from a specified ADC channel based on the input parameters. + * + * + * + * @param channel Indicates the ADC channel index. + * @param data Indicates the pointer to the address for storing the read data. + * @param equModel Indicates the equation model. + * @param curBais Indicates the analog power control mode. + * @param rstCnt Indicates the count of the time from reset to conversion start. + * One count is equal to 334 ns. The value must range from 0 to 0xFF0. + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt); +/** adc end ****/ + +/** + * @brief set WatchDog enable or disable. + * + * @param enable -- 1 enable, 0 disable. + * + * @since 1.0 + * @version 1.0 + */ +void HalSetWatchDogEnable(int enable); + +/** + * @brief start the pwm. + * + * @param id Port id of PWM + * @param duty The usefull cycles of PWM + * @param freq The total cycles of PWM + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq); + +#endif // PERIPHERAL_HAL_H \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/include/utils_hal.h b/ScenarioDemos/AstronautsGame/common/include/utils_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..a64632197cfdabc66f17f863bc7fae0dce3040e3 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/include/utils_hal.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_HAL_H__ +#define __UTILS_HAL_H__ + +void hal_udelay(uint32 us); + +#endif // __UTILS_HAL_H__ \ No newline at end of file diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/BUILD.gn b/ScenarioDemos/AstronautsGame/common/netcfg/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..0f1f3827594a59b8440de8d089ea6380ee963f9b --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("netcfg") { + sources = [ + "src/network_config.c", + "src/network_server.c", + "src/network_manager_service.c", + "src/softap.c", + "src/wifi_sta.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/include/defines.h b/ScenarioDemos/AstronautsGame/common/netcfg/include/defines.h new file mode 100755 index 0000000000000000000000000000000000000000..7d01442f2b065ac9f79df66301c7c263b32aedff --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/include/defines.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 +#define AP_NAME "HmosAP" + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#endif /* __DEFINES_H__ */ diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/include/network_config.h b/ScenarioDemos/AstronautsGame/common/netcfg/include/network_config.h new file mode 100755 index 0000000000000000000000000000000000000000..07b94be39e018c83259d86034b106b6e1e0d0dc8 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/include/network_config.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_CONFIG_H__ +#define __NETWORK_CONFIG_H__ + +#include "network_manager_service.h" + +#define NET_TASK_STACK_SIZE (1024*8) +#define NET_TASK_PRIO 31 + +/** + * @brief start net config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The NetEvent callback. event reference {@NET_EVENT_TYPE} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief stop net config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStop(void); + +/** + * @brief set net config mode + * @param mode -- reference {@NET_MODE_TYPE} + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgSetMode(int mode); + +/** + * @brief start connect the wifi + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStartConnect(const char *ssid, const char *pwd); + +#endif /* __NETWORK_CONFIG_H__ */ diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/include/network_server.h b/ScenarioDemos/AstronautsGame/common/netcfg/include/network_server.h new file mode 100755 index 0000000000000000000000000000000000000000..aa719ea56cf1bf3bcf86aba2adad4ff2ebbf5dae --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/include/network_server.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +#include "network_manager_service.h" + +#define NETSERVER_TASK_STACK_SIZE (1024*4) +#define NETSERVER_TASK_PRIO 33 + + +/** + * @brief start netserver task + * + * @param nEventCallback -- The NetEvent callback, + * when the server recv data, + * it will be called with (@NET_EVENT_RECV_DATA) + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerInit(NetManagerEventCallback nEventCallback); + +/** + * @brief stop netserver task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerDeinit(void); + +/** + * @brief set netserver task resume + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStart(void); + +/** + * @brief set netserver task suspend + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStop(void); + +/** + * @brief check the netserver when suspend or not. + * + * @since 1.0 + * @version 1.0 + * + * @return true -- netserver task is activity, false -- netserver is suspend + */ +bool NetServerIsRun(void); + +/** + * @brief send msg to client + * @param msg -- The message to send + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerSendMsg(const char *msg); + +#endif /* __NETWORK_SERVER_H__ */ diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/include/softap.h b/ScenarioDemos/AstronautsGame/common/netcfg/include/softap.h new file mode 100755 index 0000000000000000000000000000000000000000..f27a8760dd5060da5d26c0ddea2eec1fc421d213 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/include/softap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SOFT_AP_H__ +#define __SOFT_AP_H__ + +/** + * @brief start ap mode. + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int SoftApStart(const char *ap_name); + +/** + * @brief stop ap mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void SoftApStop(void); + +#endif /* __SOFT_AP_H__ */ diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/include/wifi_sta.h b/ScenarioDemos/AstronautsGame/common/netcfg/include/wifi_sta.h new file mode 100755 index 0000000000000000000000000000000000000000..824a46a056e1c488079dbc06ab13ebf832b8d1c5 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/include/wifi_sta.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_STA_H__ +#define __WIFI_STA_H__ + +#include "wifi_device.h" + +/** + * @brief wifi state change callback. + * @param state -- wifi state, 0 -- wifi not connect, 1 -- wifi connectted + * + * @since 1.0 + * @version 1.0 + * + */ +typedef void (*WifiChangeEvent)(int state); + +/** + * @brief start sta mode. + * @param WifiChange--wifi state changed callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaStart(WifiChangeEvent WifiChange); + +/** + * @brief start connect wifi. + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaConnect(const char *ssid, const char *pwd); + +/** + * @brief stop sta mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void WifiStaStop(void); + +#endif /* __WIFI_STA_H__ */ diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/src/network_config.c b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_config.c new file mode 100755 index 0000000000000000000000000000000000000000..acf6f69615bf2de4e779a241eaf5dd2287073016 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_config.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "softap.h" +#include "wifi_sta.h" + +#include "network_config.h" +#include "network_server.h" +#include "defines.h" + +#define SSID_MAX_LEN 32 +#define PWD_MAX_LEN 32 + +#define NET_PORT 8686 + +#define RETRY_TIMES 5 +#define CONNECT_TIMEOUT 20 + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "wifiName" +#define PWD_KEY "wifiPassword" + +#define CMD_CONFIG 0x20 + +typedef struct { + NET_MODE_TYPE mode; + NET_STA_TYPE status; + bool netRun; + int timeCounts; + + NetManagerEventCallback gEventCall; +} NetManagerInfo; + +static NetManagerInfo g_netManager; +const char *g_apName = NULL; + +#define SET_NET_EVENT(s, e, d) ({ \ + if (g_netManager.gEventCall != NULL) { \ + g_netManager.gEventCall(e, d); \ + } \ + g_netManager.status = s; \ +}) + +static void NetCfgConnectStatus(int s) +{ + if (s == 1 && g_netManager.status != NET_STA_CONNECTTED) { + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } else if (s == 0) { + SET_NET_EVENT(NET_STA_DISTCONNECT, NET_EVENT_DISTCONNECT, NULL); + g_netManager.mode = NET_MODE_IDLE; + } +} + +#define SHIFT_MASK 0xff +#define SHIFT_8BIT(a) (((a) >> 8) & (SHIFT_MASK)) +#define SHIFT_16BIT(a) (((a) >> 16) & (SHIFT_MASK)) +#define SHIFT_24BIT(a) (((a) >> 24) & (SHIFT_MASK)) + +static void GetIpString(uint32_t ip, char *ipAddr, int size) +{ + if (ipAddr == NULL || size <= 0) { + return; + } + + if (sprintf_s(ipAddr, size, "%d.%d.%d.%d", ip & SHIFT_MASK, SHIFT_8BIT(ip), SHIFT_16BIT(ip), SHIFT_24BIT(ip)) < 0) { + LOG_E("GetIpString failed! \n"); + } + LOG_D("ipAddr : %s \n", ipAddr); +} + +int DeviceGetIp(char *buff, int size) +{ + int ret; + long ip; + struct netif *netif_node = netif_find("wlan0"); + if (netif_node == NULL) { + LOG_E("GetLocalWifiIp netif get fail\r\n"); + return -1; + } + + ip4_addr_t ipAddr; + ip4_addr_t netMask; + ip4_addr_t gateWay; + + ret = netifapi_netif_get_addr(netif_node, &ipAddr, &netMask, &gateWay); + if (ret == 0) { + ip = ip4_addr_get_u32(&ipAddr); + GetIpString(ip, buff, size); + return 0; + } + return -1; +} + +static void SendLocalIp(int sockfd, int code) +{ + char ip[BUF_SHORT_SIZE] = {0}; + + if (code == REQUEST_OK) { + if (DeviceGetIp(ip, sizeof(ip)) < 0) { + LOG_E("get local ip failed! \n"); + return; + } + } + + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, "code", code); + json_pobject obj1, obj2; + + if (code != REQUEST_OK) { + obj1 = add_string_to_object(json, "errmsg", "connect wifi failed!"); + obj1 = add_object_to_object(json, "result"); + } else { + obj1 = add_object_to_object(json, "result"); + obj2 = add_number_to_object(obj1, "cmd", CMD_CONFIG); + obj2 = add_string_to_object(obj1, "ip", (const char *)ip); + } + + char *msg = json_to_string(json); + const char *eof = "\r\n"; + LOG_D("send msg : %s \n", msg); + if (send(sockfd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return; + } + send(sockfd, eof, strlen(eof), 0); + + delete_json_object(json); +} + +static int NetCfgConnect(const char *ssid, const char *pwd, bool wait) +{ + int timecnt = 0; + int retval = 0; + if (WifiStaStart(NetCfgConnectStatus) < 0) { + LOG_E("wifista_start \n"); + return -1; + } + + if (WifiStaConnect((const char *)ssid, (const char *)pwd) < 0) { + LOG_E("hal_wifi_start_connect \n"); + return -1; + } + + if (wait) { + while (g_netManager.status != NET_STA_CONNECTTED) { + usleep(USLEEP_500MS); + if (++timecnt > CONNECT_TIMEOUT) { + retval = -1; + break; + } + } + } + + return retval; +} + +static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl) +{ + json_handle json; + json_pobject sub; + + int cmd; + char *ps = NULL; + char *pw = NULL; + + json = parse_json(psr); + if (json == NULL) { + LOG_E("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + if (cmd != CMD_CONFIG) { + LOG_E("CMD TYPE FAILED! cmd=%d \n", cmd); + return -1; + } + + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + LOG_E("get param obj failed! \n"); + free_json(json); + return -1; + } + ps = get_json_string(sub, VAL_KEY); + if (ps == NULL) { + LOG_E("get ssid failed! \n"); + free_json(json); + return -1; + } + + if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + pw = get_json_string(sub, PWD_KEY); + if (pw != NULL) { + LOG_D("pw=%s\n", pw); + if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + } + + free_json(json); + return 0; +} + +static int NetCfgGetSocketValue(int sockfd) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + struct sockaddr_in addr; + socklen_t len; + int result = -1; + char ssid[SSID_MAX_LEN + 1] = {0}; + char pwd[PWD_MAX_LEN + 1] = {0}; + while (1) { + int readBytes; + len = sizeof(addr); + if (g_netManager.mode != NET_MODE_CONFIG) { + break; + } + if (memset_s(recvbuf, BUF_SHORT_SIZE, 0, BUF_SHORT_SIZE) < 0) { + break; + } + readBytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len); + if (readBytes <= 0) { + LOG_E("socket disconnect! \n"); + break; + } + if (ParseWifiInfo((const char*)recvbuf, ssid, sizeof(ssid), pwd, sizeof(pwd)) == 0) { + result = 0; + break; + } + } + if (result != -1) { + int code = REQUEST_OK; + SET_NET_EVENT(NET_STA_CONNECTTING, NET_EVENT_CONNECTTING, NULL); + if (NetCfgConnect(ssid, pwd, true) < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONN_FAILED, NULL); + code = REQUEST_ERR; + WifiStaStop(); + result = -1; + } else { + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } + + usleep(USLEEP_2500MS); // wait ip ready + SendLocalIp(sockfd, code); + usleep(USLEEP_1000MS); + if (result != -1) { + NetServerStart(); + } + } + if (memset_s(pwd, sizeof(pwd), 0x00, sizeof(pwd)) < 0) { + return -1; + } + return result; +} + +static int NetCfgSocket(void) +{ + int sockfd; + struct sockaddr_in servaddr; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + LOG_E("socket error! \n"); + return -1; + } + + memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(NET_PORT); + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + LOG_D("监听%d端口\n", NET_PORT); + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { + LOG_E("bind socket! \n"); + close(sockfd); + return -1; + } + + if (listen(sockfd, 1) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + close(sockfd); + return -1; + } + + while (g_netManager.mode == NET_MODE_CONFIG) { + int newfd, retval; + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length); + LOG_D("new socket connect!\n"); + retval = NetCfgGetSocketValue(newfd); + close(newfd); + + if (retval == 0) { + LOG_D("config network success! \n"); + g_netManager.mode = NET_MODE_STA; + } + } + + close(sockfd); + + return 0; +} + +static void NetCfgStartConfig(void) +{ + SET_NET_EVENT(NET_STA_CONFIG, NET_EVENT_CONFIG, NULL); + WifiStaStop(); + if (SoftApStart(g_apName) < 0) { + LOG_E("start softap failed! \n"); + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + if (NetCfgSocket() < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + SoftApStop(); +} + +static void *NetCfgTask(void *arg) +{ + (void)arg; + int netCfgMode = NET_STA_NULL; + while (g_netManager.netRun) { + if (netCfgMode == g_netManager.mode && netCfgMode != NET_MODE_STA) { + usleep(USLEEP_1000MS); + continue; + } + if (netCfgMode != g_netManager.mode) { + netCfgMode = g_netManager.mode; + } + switch (netCfgMode) { + case NET_MODE_CONFIG: + NetCfgStartConfig(); + break; + default: + break; + } + usleep(USLEEP_1000MS); + } + + return NULL; +} + +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + + if (memset_s(&g_netManager, sizeof(g_netManager), 0x00, sizeof(g_netManager)) < 0) { + LOG_E("memset_s g_netManager \n"); + return -1; + } + + g_netManager.gEventCall = nEventCallback; + g_netManager.netRun = true; + g_netManager.mode = NET_STA_CONFIG; + g_apName = apName; + attr.name = "NetManagerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NET_TASK_STACK_SIZE; + attr.priority = NET_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)NetCfgTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetManagerTask!\n"); + return -1; + } + + return 0; +} + +void NetCfgStop(void) +{ + g_netManager.netRun = false; +} + +void NetCfgSetMode(int mode) +{ + g_netManager.mode = mode; +} + +void NetCfgStartConnect(const char *ssid, const char *pwd) +{ + NetCfgConnect(ssid, pwd, false); +} diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/src/network_manager_service.c b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_manager_service.c new file mode 100755 index 0000000000000000000000000000000000000000..1ebcd2c337e92bd80bf0645763e3c84e4dbb76fc --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_manager_service.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "network_server.h" +#include "network_config.h" +#include "defines.h" + +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback) +{ + if (NetServerInit(nEventCallback) < 0) { + LOG_E("NetServerInit \n"); + return -1; + } + + if (NetCfgStart(apName, nEventCallback) < 0) { + LOG_E("NetCfgStart \n"); + NetServerDeinit(); + return -1; + } + + return 0; +} + +void NetManagerUnRegister(void) +{ + NetServerDeinit(); + NetCfgStop(); +} + +void NetManagerSetNetMode(int mode) +{ + NetCfgSetMode(mode); +} + +int NetManagerSendMsg(const char *msg) +{ + return NetServerSendMsg(msg); +} diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/src/network_server.c b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_server.c new file mode 100755 index 0000000000000000000000000000000000000000..5ef795c2a5095b36f9f3c3871234426d16a19fb4 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/src/network_server.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "common_log.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "json/jsonutil.h" +#include "network_server.h" +#include "defines.h" + +#define SERVER_PORT 8787 +#define MAX_CONNECT 10 + +typedef struct { + int sockfd[MAX_CONNECT]; + int connAmount; + bool isActive; + bool serRun; + + NetManagerEventCallback g_call; +}NetServerInfo; + +static NetServerInfo g_netServer; + +static int NetServerSend(int fd, const char *msg) +{ + const char *eof = "\r\n"; + if (send(fd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return -1; + } + LOG_D("send msg : %s \n", msg); + send(fd, eof, strlen(eof), 0); + + return 0; +} + +static void SendRequest(int sockfd, int code) +{ + json_pobject obj; + json_pobject json = create_json_object(); + + obj = add_number_to_object(json, "code", code); + if (code == REQUEST_OK) { + obj = add_string_to_object(json, "errmsg", ""); + } else { + obj = add_string_to_object(json, "errmsg", "explain params error!"); + } + + char *msg = json_to_string(json); + NetServerSend(sockfd, msg); + delete_json_object(json); +} + +static bool IsSpecialSocket(const char *msg) +{ + char buf[] = {0xff, 0x55, 0xaa, 0x55, 0x00}; + bool result = true; + if (msg == NULL || strlen(msg) < strlen(buf)) { + return false; + } + + for (int i = 0; i < strlen(buf); i++) { + if (msg[i] != buf[i]) { + result = false; + break; + } + } + + return result; +} + +static int ReadHandle(int *sockfd, fd_set *fdSet) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + int recvbytes; + int fd = *sockfd; + int errcode = -1; + + recvbytes = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0); + if (recvbytes <= 0) { + LOG_D("socket may quit!\n"); + FD_CLR(fd, fdSet); + close(fd); + *sockfd = -1; + g_netServer.connAmount--; + return -1; + } + + if (g_netServer.sockfd[0] == -1 && IsSpecialSocket(recvbuf)) { + *sockfd = -1; + g_netServer.sockfd[0] = fd; + return 0; + } + + LOG_D("recv msg[%d] : %s \n", recvbytes, recvbuf); + if (g_netServer.g_call) { + errcode = g_netServer.g_call(NET_EVENT_RECV_DATA, recvbuf); + } + + if (errcode == -1) { + errcode = REQUEST_ERR; + } else { + errcode = REQUEST_OK; + } + + SendRequest(fd, errcode); + + return 0; +} + +static void CheckNewSocket(int sockFd, fd_set *fdSet, int *maxFd) +{ + int newfd; + struct sockaddr_in client_addr; + socklen_t sin_size = sizeof(client_addr); + if (FD_ISSET(sockFd, fdSet) == 0) { + return; + } + + newfd = accept(sockFd, (struct sockaddr *)&client_addr, &sin_size); + LOG_D("accept:: sock_fd = %d, newfd = %d\n", sockFd, newfd); + if (newfd <= 0) { + LOG_E("accept:\n"); + return; + } + + g_netServer.connAmount++; + + if (g_netServer.connAmount < MAX_CONNECT) { + for (int i = 1; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] == -1) { + g_netServer.sockfd[i] = newfd; + break; + } + } + + if (newfd > *maxFd) { + *maxFd = newfd; + } + } else { + LOG_E("max connections arrive, exit\n"); + close(newfd); + } +} + +static void SocketListen(int sock_fd) +{ + fd_set fdset; + int maxsock; + maxsock = sock_fd; + + while (g_netServer.serRun) { + int ret; + struct timeval tv = {2, 0}; + FD_ZERO(&fdset); + FD_SET(sock_fd, &fdset); + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + FD_SET(g_netServer.sockfd[i], &fdset); + } + } + ret = select(maxsock + 1, &fdset, NULL, NULL, &tv); + if (ret <= 0) { + continue; + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1 && FD_ISSET(g_netServer.sockfd[i], &fdset)) { + LOG_D("g_netServer.sockfd[%d] = %d\n", i, g_netServer.sockfd[i]); + ReadHandle(&g_netServer.sockfd[i], &fdset); + continue; + } + } + + CheckNewSocket(sock_fd, &fdset, &maxsock); + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + close(g_netServer.sockfd[i]); + g_netServer.sockfd[i] = -1; + } + } +} + +static void StartServer(void) +{ + struct sockaddr_in serv_addr; + int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) { + LOG_E("socket failed! \n"); + g_netServer.serRun = false; + return; + } + + if (memset_s(&serv_addr, sizeof(serv_addr), 0, sizeof(serv_addr)) < 0) { + LOG_E("memset_s faield! \n"); + close(sockfd); + g_netServer.serRun = false; + return; + } + + serv_addr.sin_family = AF_INET; // 使用IPv4地址 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(SERVER_PORT); // 端口 + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + LOG_E("bind failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + if (listen(sockfd, MAX_CONNECT) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + SocketListen(sockfd); + + LOG_D("SOCKET SERVER QUIT! \n"); + + close(sockfd); +} + +static void *NetServerTask(void *param) +{ + while (g_netServer.isActive) { + if (g_netServer.serRun == false) { + usleep(USLEEP_100MS); + continue; + } + + StartServer(); + } + + return NULL; +} + +int NetServerInit(NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + attr.name = "NetServerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NETSERVER_TASK_STACK_SIZE; + attr.priority = NETSERVER_TASK_PRIO; + + if (memset_s(&g_netServer, sizeof(g_netServer), 0x00, sizeof(g_netServer)) < 0) { + LOG_E("memset_s failed! \n"); + return -1; + } + for (int i = 0; i < MAX_CONNECT; i++) { + g_netServer.sockfd[i] = -1; + } + g_netServer.isActive = true; + g_netServer.g_call = nEventCallback; + if (osThreadNew((osThreadFunc_t)NetServerTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetServerTask!\n"); + g_netServer.isActive = false; + return -1; + } + + return 0; +} + +void NetServerDeinit(void) +{ + g_netServer.serRun = false; + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + shutdown(g_netServer.sockfd[i], SHUT_RDWR); + g_netServer.sockfd[i] = -1; + } + } + + osDelay(DELAY_200MS); + g_netServer.isActive = false; +} + +void NetServerStart(void) +{ + g_netServer.serRun = true; +} + +void NetServerStop(void) +{ + g_netServer.serRun = false; + osDelay(DELAY_200MS); +} + +bool NetServerIsRun(void) +{ + return g_netServer.serRun; +} + +int NetServerSendMsg(const char *msg) +{ + if (g_netServer.serRun == false || g_netServer.sockfd[0] == -1) { + LOG_E("net server is not run! \n"); + return -1; + } + + return NetServerSend(g_netServer.sockfd[0], msg); +} diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/src/softap.c b/ScenarioDemos/AstronautsGame/common/netcfg/src/softap.c new file mode 100755 index 0000000000000000000000000000000000000000..6fb27d2a74baf4ba7f6b0bd4dd3750c5196bdad9 --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/src/softap.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "softap.h" +#include "defines.h" + +static void ResetAddr(struct netif *pst_lwip_netif) +{ + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + + IP4_ADDR(&st_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&st_gw, 0, 0, 0, 0); + IP4_ADDR(&st_netmask, 0, 0, 0, 0); + + netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw); +} + +int SoftApStart(const char *ap_name) +{ + HotspotConfig config = {0}; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + char *apName = ap_name; + char ifname[BUF_SHORT_SIZE] = {0}; + int retval; + + if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_ACTIVE \n"); + return -1; + } + if (apName == NULL) { + apName = AP_NAME; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), apName) != 0) { + printf("[sample] strcpy ssid fail.\n"); + return -1; + } + config.securityType = WIFI_SEC_TYPE_OPEN; + retval = SetHotspotConfig((const HotspotConfig *)(&config)); + if (retval != WIFI_SUCCESS) { + LOG_E("SetHotspotConfig \n"); + return -1; + } + + retval = EnableHotspot(); + if (retval != WIFI_SUCCESS) { + LOG_E("EnableHotspot failed! \n"); + return -1; + } + return 0; +} + +void SoftApStop(void) +{ + if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_NOT_ACTIVE \n"); + return; + } + + DisableHotspot(); +} diff --git a/ScenarioDemos/AstronautsGame/common/netcfg/src/wifi_sta.c b/ScenarioDemos/AstronautsGame/common/netcfg/src/wifi_sta.c new file mode 100755 index 0000000000000000000000000000000000000000..ffb4bc775ca4e9c801e210deef3d73a2e409687c --- /dev/null +++ b/ScenarioDemos/AstronautsGame/common/netcfg/src/wifi_sta.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_sta.h" +#include "defines.h" + +#define TEST_CONNECT_RETRY_COUNT 5 + +static WifiEvent g_staEventHandler = {0}; +static WifiChangeEvent g_wifiChange = NULL; +static int g_connectRetryCount = 0; + +static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (state == WIFI_STATE_AVALIABLE) { + LOG_I("WiFi: Connected.\n"); + g_connectRetryCount = 0; + } else if (state == WIFI_STATE_NOT_AVALIABLE) { + LOG_I("WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason); + if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) { + g_connectRetryCount++; + return; + } + } + if (g_wifiChange) { + g_wifiChange(state); + } +} + +int WifiStaStart(WifiChangeEvent WifiChange) +{ + WifiErrorCode error; + + g_wifiChange = WifiChange; + + if (IsWifiActive() == WIFI_STA_ACTIVE) { + LOG_E("the wifi has been enabled! \n"); + return 1; + } + + error = EnableWifi(); + if (error != WIFI_SUCCESS) { + LOG_E("EnableWifi failed! \n"); + return -1; + } + + g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler; + error = RegisterWifiEvent(&g_staEventHandler); + if (error != WIFI_SUCCESS) { + LOG_E("RegisterWifiEvent fail, error = %d\n", error); + return -1; + } + + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return -1; + } + + return 0; +} + +int WifiStaConnect(const char *ssid, const char *pwd) +{ + WifiDeviceConfig config = {0}; + int netId = 0; + WifiErrorCode error; + + if (ssid == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), ssid) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + + config.ipType = DHCP; + if (pwd == NULL || strlen(pwd) == 0) { + config.securityType = WIFI_SEC_TYPE_OPEN; + } else { + config.securityType = WIFI_SEC_TYPE_PSK; + if (strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), pwd) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + } + + error = AddDeviceConfig(&config, &netId); + if (error != WIFI_SUCCESS) { + LOG_E("AddDeviceConfig! \n"); + return -1; + } + + error = ConnectTo(netId); + if (error != WIFI_SUCCESS) { + LOG_E("ConnectTo! \n"); + return -1; + } + + return 0; +} + +void WifiStaStop(void) +{ + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return; + } + + DisableWifi(); + UnRegisterWifiEvent(&g_staEventHandler); +} + diff --git a/ScenarioDemos/AstronautsGame/screenshoot/device/Astronautsgame.png b/ScenarioDemos/AstronautsGame/screenshoot/device/Astronautsgame.png new file mode 100755 index 0000000000000000000000000000000000000000..7050f4bd5ef75d2489207011558ace1eb7347c55 Binary files /dev/null and b/ScenarioDemos/AstronautsGame/screenshoot/device/Astronautsgame.png differ diff --git a/ScenarioDemos/DistributedSearch/README_zh.md b/ScenarioDemos/DistributedSearch/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..20fd973f27a99fab25eb7e928a473a70acf937ba --- /dev/null +++ b/ScenarioDemos/DistributedSearch/README_zh.md @@ -0,0 +1,38 @@ +# **分布式搜索** + +##### 简介 + +​ 本sample由Java开发,通过搜索本地的图片,音频及视频文件,并加入到分布式文件系统中,实现文件快速共享。用户可以通过输入关键字搜索到分布式文件系统中的所有文件。 + +##### 使用说明 + +1. 搜索 + 输入框输入关键字,可以通过输入框后面的搜索按钮进行搜索,也可以通过选择类型进行对应类别的搜索。 +2. 结果显示 + 搜索完后,数据将以列表的形式显示在显示区域。 + 点击每行可以查看到文件的具体路径。 + 如果没有搜索到文件,则显示无搜索结果的界面。 +3. 分布式设备查看 + 点击主界面右下角的设备按钮,可以查看到当前已经加入到分布式系统的设备情况。 + +##### 约束与限制 + +1. 编译约束 + 已实名认证的开发者联盟账号 ,具体[参考](https://developer.huawei.com/consumer/cn/ ) + 开发工具:DevEcoStudio 2.2Beta1 下载地址 [HUAWEI DevEco Studio - HarmonyOS应用开发官网](https://developer.harmonyos.com/cn/develop/deveco-studio#download) + + •安装DevEco Studio + + 设置DevEco Studio开发环境,DevEco Studio开发环境需要连接到网络,以确保该正常使用。 + 可以根据以下两种情况配置开发环境: + 1).如果您可以直接访问Internet,则只需下载HarmonyOS SDK + 2).如果网络无法直接访问Internet,则可以通过代理服务器进行访问 • 生成密钥并申请证书 + + 具体环境搭建请[参考:](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/installation_process-0000001071425528) + 更多资料请登录鸿蒙应用开发[官网:](https://developer.harmonyos.com/cn/) + +2. 使用限制 + •该应用必须要有两部或以上同一组网内的手机 + •多手机必须登录同一用户 + •暂时只支持外部SD卡中的图片,音频以及视频文件的搜索 + diff --git a/ScenarioDemos/DistributedSearch/build.gradle b/ScenarioDemos/DistributedSearch/build.gradle new file mode 100755 index 0000000000000000000000000000000000000000..5753d7a6eac988a4367cdef28e0eb7eb995b6926 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/build.gradle @@ -0,0 +1,38 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + classpath 'com.huawei.ohos:decctest:1.2.4.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/build.gradle b/ScenarioDemos/DistributedSearch/entry/build.gradle new file mode 100755 index 0000000000000000000000000000000000000000..61249ffabf18d2d36cff33b5cfb5809add2943c9 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' +} +decc { + supportType = ['html','xml'] +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/config.json b/ScenarioDemos/DistributedSearch/entry/src/main/config.json new file mode 100755 index 0000000000000000000000000000000000000000..6acb81fc0774e58aaf53e9bcd172db1038bc7b58 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/config.json @@ -0,0 +1,107 @@ +{ + "app": { + "bundleName": "ohos.samples.distributedsearch", + "vendor": "sample", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.distributedsearch", + "name": ".MyApplication", + "mainAbility": "ohos.samples.distributedsearch.MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "reqPermissions": [ + { + "name": "ohos.permission.DISTRIBUTED_DATASYNC", + "reason": "用于分布式数据交换", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" + }, + { + "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE" + }, + { + "name": "ohos.permission.READ_USER_STORAGE", + "reason": "用于读取用户存储信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.WRITE_USER_STORAGE", + "reason": "用于写取用户存储信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.READ_MEDIA", + "reason": "用于读取媒体文件信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.WRITE_MEDIA", + "reason": "用于保存媒体文件信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO" + } + ], + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "ohos.samples.distributedsearch.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ] + } +} \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java new file mode 100755 index 0000000000000000000000000000000000000000..c7ff81299f30514b54802a0cf1b238c348d11b9d --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch; + +import ohos.bundle.IBundleManager; +import ohos.samples.distributedsearch.slice.MainAbilitySlice; +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.security.SystemPermission; + +import java.util.ArrayList; +import java.util.List; + +public class MainAbility extends Ability { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(MainAbilitySlice.class.getName()); + + requestPermissions(); + } + + private void requestPermissions() { + String[] permissions = { + SystemPermission.DISTRIBUTED_DATASYNC, + SystemPermission.READ_USER_STORAGE, + SystemPermission.WRITE_USER_STORAGE + }; + List permissionsToProcess = new ArrayList<>(); + for (String permission : permissions) { + if (verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED + && canRequestPermission(permission)) { + permissionsToProcess.add(permission); + } + } + requestPermissionsFromUser(permissionsToProcess.toArray(new String[0]), 0); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java new file mode 100755 index 0000000000000000000000000000000000000000..3dbcb403b07cf9f6f70c306277f121462dbdc7fb --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ohos.samples.distributedsearch; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java new file mode 100755 index 0000000000000000000000000000000000000000..0f67e6046b4380403951dab11cff5453abca3d30 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.data; + +import ohos.distributedschedule.interwork.DeviceInfo; + +/** + * The type Device data. + * + * @since 2021-04-27 + */ +public class DeviceData { + private boolean isChecked; + + private DeviceInfo deviceInfo; + + /** + * Instantiates a new Device data. + */ + public DeviceData() { + } + + /** + * Instantiates a new Device data. + * + * @param isChecked the is checked + * @param deviceInfo the device info + */ + public DeviceData(boolean isChecked, DeviceInfo deviceInfo) { + this.isChecked = isChecked; + this.deviceInfo = deviceInfo; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + public DeviceInfo getDeviceInfo() { + return deviceInfo; + } + + public void setDeviceInfo(DeviceInfo deviceInfo) { + this.deviceInfo = deviceInfo; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java new file mode 100755 index 0000000000000000000000000000000000000000..f83e0b7fb6db36b870e48b11e2976a0c3c74d0e7 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * The type Comment view holder. + * + * @since 2021-04-27 + */ +public class ComponentViewHolder { + /** + * Layout + */ + private Component componentView; + + /** + * Subcomponents in componentview + */ + private final Map childComponentMap = new HashMap<>(); + + /** + * Instantiates a new Component view holder. + */ + public ComponentViewHolder() { + } + + /** + * Instantiates a new Component view holder. + * + * @param componentView the component view + */ + public ComponentViewHolder(Component componentView) { + this.componentView = componentView; + componentView.setTag(this); + } + + public Component getComponentView() { + return componentView; + } + + /** + * Obtain the corresponding component according to the resource ID + * + * @param resId resId + * @return Component + */ + public Component getChildComponent(int resId) { + Component view = childComponentMap.get(resId); + if (view == null) { + view = componentView.findComponentById(resId); + childComponentMap.put(resId, view); + } + return view; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java new file mode 100755 index 0000000000000000000000000000000000000000..19ce062b64d4fc19e8985c02067b6dc032a2e9c9 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.Component; +import ohos.agp.components.Image; +import ohos.agp.components.Text; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.data.DeviceData; + +import java.util.List; + +/** + * The type Device data provider. + * + * @since 2021-04-27 + */ +public class DeviceDataProvider extends ListComponentProvider { + /** + * Instantiates a new Device data provider. + * + * @param context the context + * @param listBean the list bean + * @param resourceId the resource id + */ + public DeviceDataProvider(Context context, List listBean, int resourceId) { + super(context, listBean, resourceId); + } + + @Override + public void onItemDataBind(ComponentViewHolder componentViewHolder, DeviceData deviceData, int position) { + // 1 Set the name of the device + Text deviceText = (Text) componentViewHolder.getChildComponent(ResourceTable.Id_item_image_title); + deviceText.setText(deviceData.getDeviceInfo().getDeviceName()); + Text infoText = (Text) componentViewHolder.getChildComponent(ResourceTable.Id_item_image_info); + infoText.setText(deviceData.getDeviceInfo().getDeviceId()); + // 2 Set icon for device + setDeviceImg(componentViewHolder, deviceData); + } + + private void setDeviceImg(ComponentViewHolder componentViewHolder, DeviceData deviceData) { + Integer imageTypeId = null; + switch (deviceData.getDeviceInfo().getDeviceType()) { + case SMART_PHONE: + imageTypeId = ResourceTable.Media_dv_phone; + break; + case SMART_PAD: + imageTypeId = ResourceTable.Media_dv_pad; + break; + case SMART_WATCH: + imageTypeId = ResourceTable.Media_dv_watch; + break; + default: + break; + } + if (imageTypeId != null) { + Image image = (Image) componentViewHolder.getChildComponent(ResourceTable.Id_item_type); + image.setPixelMap(imageTypeId); + } + } + + @Override + public void onItemClick(Component component, DeviceData checkDeviceData, int position) { + for (DeviceData deviceData : listBean) { + deviceData.setChecked(false); + } + listBean.get(position).setChecked(true); + // Notify data changes + notifyDataChanged(); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java new file mode 100755 index 0000000000000000000000000000000000000000..a3c6c24c5be0e1db6c17224b03be63b46c811e4e --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +public class FileItemViewHolder { + private String filename; + private String devicename; + private int iconId; + private String filepath; + + public FileItemViewHolder(String fName, String dName, int icon) { + iconId = icon; + filename = fName; + devicename = dName; + } + + public FileItemViewHolder(String fName, String pName, String dName, int icon) { + iconId = icon; + filename = fName; + devicename = dName; + filepath = pName; + } + + public void setFilename(String f) { + filename = f; + } + public String getFilename() { + return filename; + } + + public void setDevicename(String i) { + devicename = i; + } + public String getDevicename() { + return devicename; + } + + public void setIconId(int icon) { + iconId = icon; + } + public int getIconId() { + return iconId; + } + + public void setFilepath(String p) { + filepath = p; + } + public String getFilepath() { + return filepath; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java new file mode 100755 index 0000000000000000000000000000000000000000..924550d40d95d35d3718b2abdb7ea62d7d920fea --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.BaseItemProvider; +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.Image; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.utils.LogUtil; + +import java.util.List; + +public class FileListProvider extends BaseItemProvider { + private final static String TAG = "FileListProvider"; + private final Context mContext; + private final List mList; + + public FileListProvider(Context context, List listBean){ + mContext = context; + mList = listBean; + } + + @Override + public int getCount() { + return mList == null ? 0 : mList.size(); + } + + @Override + public T getItem(int i) { + + return (mList == null || mList.size() == 0) ? null : mList.get(i); + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public Component getComponent(int i, Component component, ComponentContainer componentContainer) { + FileItemViewHolder holder; + + if (component == null) { + component = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_file_item, null, false); + } + + holder = (FileItemViewHolder)mList.get(i); + if (holder == null) { + LogUtil.error(TAG, "FileItemViewHolder[]"+ i + " is null"); + return component; + } + + Image icon = (Image)component.findComponentById(ResourceTable.Id_imageIcon); + icon.setPixelMap(holder.getIconId()); + + Text name = (Text)component.findComponentById(ResourceTable.Id_filename); + name.setText(holder.getFilename()); + Text devName = (Text)component.findComponentById(ResourceTable.Id_deviceinfo); + devName.setText(mContext.getString(ResourceTable.String_file_source_label) + ": " + holder.getDevicename()); + + return component; + } + + /** + * Set the binding event of item, and the subclass overrides as needed + * + * @param component component + * @param item item + * @param position position + */ + protected void onItemClick(Component component, T item, int position) { + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java new file mode 100755 index 0000000000000000000000000000000000000000..5afd8f713aec6101aa8da7f70d5625cd5d62894c --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.BaseItemProvider; +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.LayoutScatter; +import ohos.app.Context; + +import java.util.List; + +/** + * The type List component provider. + * + * @param the type parameter + * @since 2021-04-27 + */ +public abstract class ListComponentProvider extends BaseItemProvider { + protected Context context; + + /** + * Item data + */ + protected List listBean; + + /** + * Layout resource id + */ + protected int resourceId; + + /** + * Instantiates a new List component provider. + * + * @param context the context + * @param listBean the list bean + * @param resourceId the resource id + */ + public ListComponentProvider(Context context, List listBean, int resourceId) { + this.context = context; + this.listBean = listBean; + this.resourceId = resourceId; + } + + /** + * Set the data of the view subcomponent + * + * @param componentViewHolder componentViewHolder + * @param item item + * @param position position + */ + protected abstract void onItemDataBind(ComponentViewHolder componentViewHolder, T item, int position); + + @Override + public int getCount() { + return listBean.size(); + } + + @Override + public T getItem(int i) { + return listBean.get(i); + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public Component getComponent(int position, Component component, ComponentContainer componentContainer) { + ComponentViewHolder viewHolder; + if (component == null) { + component = LayoutScatter.getInstance(context).parse(resourceId, null, false); + viewHolder = new ComponentViewHolder(component); + component.setTag(viewHolder); + } else { + viewHolder = (ComponentViewHolder) component.getTag(); + } + if (viewHolder != null) { + T item = listBean.get(position); + // Set the data of the view subcomponent + onItemDataBind(viewHolder, item, position); + // Set binding event of item + viewHolder.getComponentView() + .setClickedListener(componentView -> onItemClick(componentView, item, position)); + } + return component; + } + + /** + * Set the binding event of item, and the subclass overrides as needed + * + * @param component component + * @param item item + * @param position position + */ + protected void onItemClick(Component component, T item, int position) { + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java new file mode 100755 index 0000000000000000000000000000000000000000..036f01451ed9c84193653d13163eeed3d7f13507 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java @@ -0,0 +1,250 @@ +package ohos.samples.distributedsearch.slice; + +import ohos.agp.components.*; +import ohos.agp.utils.Color; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.samples.distributedsearch.provider.FileItemViewHolder; +import ohos.samples.distributedsearch.provider.FileListProvider; +import ohos.samples.distributedsearch.ui.DeviceSelectDialog; +import ohos.samples.distributedsearch.ui.PopupDialog; +import ohos.samples.distributedsearch.utils.DeviceUtils; +import ohos.samples.distributedsearch.utils.DistributedFile; +import ohos.samples.distributedsearch.utils.WidgetHelper; + +import java.util.ArrayList; +import java.util.List; + +public class MainAbilitySlice extends AbilitySlice { + private String gSearchKey = ""; + private TextField gTextField; + private int gFileType = DistributedFile.FILE_TYPE_IMAGE; + + private RadioButton mButtonImage; + private RadioButton mButtonAudio; + private RadioButton mButtonVideo; + private RadioButton mButtonText; + private RadioButton mButtonFileAll; + FileListProvider fileProvider; + private final ArrayList mFileList = new ArrayList<>(); + private ListContainer listview; + private Text result; + private Image mButton; + private Button mDevice; + private DistributedFile mDistributedFile; + private RadioContainer mRadioContainer; + private Image searchImage; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_ability_everything); + + mDistributedFile = new DistributedFile(this); + mDistributedFile.start(); + + initUI(); + setEventListener(); + } + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } + + private void initUI() { + listview = (ListContainer)this.findComponentById(ResourceTable.Id_listview); + fileProvider = new FileListProvider(this, mFileList); + listview.setItemProvider(fileProvider); + + listview.setVisibility(Component.HIDE); + + result = (Text) findComponentById(ResourceTable.Id_result_info); + result.setVisibility(Component.VISIBLE); + + mRadioContainer = (RadioContainer)findComponentById(ResourceTable.Id_radio_container); + + mButtonImage = (RadioButton) this.findComponentById(ResourceTable.Id_sel_image); + mButtonAudio = (RadioButton) this.findComponentById(ResourceTable.Id_sel_audio); + mButtonVideo = (RadioButton) this.findComponentById(ResourceTable.Id_sel_video); + mButtonText = (RadioButton) this.findComponentById(ResourceTable.Id_sel_text); + mButtonFileAll = (RadioButton) this.findComponentById(ResourceTable.Id_sel_all); + mRadioContainer.mark(0); + mButtonImage.setClickable(false); + + gTextField = (TextField)this.findComponentById(ResourceTable.Id_textEntry); + gTextField.setTextColor(Color.BLACK); + searchImage = (Image)this.findComponentById(ResourceTable.Id_searchButton); + + mButton = (Image)findComponentById(ResourceTable.Id_AnimaBttn); + mDevice = (Button)findComponentById(ResourceTable.Id_deviceBttn); + + mButton.setPosition(350, 700); + mDevice.setPosition(320, 700); + mButton.setVisibility(Component.VISIBLE); + mDevice.setVisibility(Component.HIDE); + } + + private void setEventListener() { + setListViewEvent(); + setRadioContainerEvent(); + + searchImage.setClickedListener(component -> { + gSearchKey = gTextField.getText(); + if (!availableKey(gSearchKey)) { + WidgetHelper.showTips(this, getString(ResourceTable.String_input_notice_msg), 2000); + return; + } + + setListFile(); + }); + + mButton.setClickedListener(component -> { + mButton.setVisibility(Component.HIDE); + if (mDevice != null) { + mDevice.setVisibility(Component.VISIBLE); + mDevice.setFocusable(Component.FOCUS_ENABLE); + } + }); + + mDevice.setClickedListener(component -> { + + mDevice.setVisibility(Component.HIDE); + if (mButton != null) { + mButton.setVisibility(Component.VISIBLE); + mButton.setFocusable(Component.FOCUS_ENABLE); + } + DeviceSelectDialog mDialog = new DeviceSelectDialog(this); + mDialog.show(); + }); + } + + private void setListViewEvent() { + listview.setItemClickedListener((container, component, position, id) ->{ + FileItemViewHolder item = (FileItemViewHolder) listview.getItemProvider().getItem(position); + if (item != null && item.getFilepath() != null) { + WidgetHelper.showTips(this, + getString(ResourceTable.String_file_path_label) + ": " + + item.getFilepath() + "/" + item.getFilename(), 2000); + } + }); + listview.setItemLongClickedListener((container, component, position, id) ->{ + FileItemViewHolder item = (FileItemViewHolder) listview.getItemProvider().getItem(position); + if (item != null) { + PopupDialog mDialog = new PopupDialog(this); + mDialog.show(); + } + return true; + }); + } + + private void setRadioContainerEvent() { + mRadioContainer.setMarkChangedListener((radioContainer, i) -> { + RadioButton[] mRadioButton = { + mButtonImage, + mButtonAudio, + mButtonVideo, + mButtonText, + mButtonFileAll + }; + + if (gFileType == i) { + return; + } + + if (mRadioButton[gFileType] != null) { + mRadioButton[gFileType].setTextColor(Color.GRAY); + mRadioButton[gFileType].setClickable(true); + } + gFileType = i; + mRadioButton[gFileType].setClickable(false); + + gSearchKey = gTextField.getText(); + if (availableKey(gSearchKey)) { + setListFile(); + } + }); + } + + private boolean getFileViewList() { + List list; + if (!mDistributedFile.hasCheckResult()) { + return false; + } + list = mDistributedFile.getFile(gFileType); + if (list == null || list.size() == 0) { + return false; + } + + getFileList(list, gSearchKey); + + return mFileList.size() > 0; + } + + private void getFileList(List list, String key) { + mFileList.clear(); + for (String filename : list) { + String device; + String name; + String path = null; + + int idx = filename.lastIndexOf('/'); + if (idx < 0) { + name = filename; + } else { + name = filename.substring(idx+1); + path = filename.substring(0, idx+1); + } + idx = name.indexOf('+'); + if (idx < 0) { + device = getString(ResourceTable.String_local_device_name); + } else { + device = name.substring(0, idx); + if (DeviceUtils.isLocalDevice(this, device, DeviceUtils.DEVICE_TYPE_NAME)) { + device = getString(ResourceTable.String_local_device_name); + } + name = name.substring(idx+1); + } + + if (filename.contains(key)) { + int ico = ResourceTable.Media_icon_file; + int type = mDistributedFile.checkFileType(name); + + if (type == DistributedFile.FILE_TYPE_IMAGE) { + ico = ResourceTable.Media_icon_img; + } else if (type == DistributedFile.FILE_TYPE_AUDIO) { + ico = ResourceTable.Media_icon_music; + } else if (type == DistributedFile.FILE_TYPE_VIDEO) { + ico = ResourceTable.Media_icon_video; + } + + FileItemViewHolder viewHolder = new FileItemViewHolder(name, path, device, ico); + mFileList.add(viewHolder); + } + } + } + + private boolean availableKey(String key) { + if (key == null || key.length() == 0) { + return false; + } + return !key.contains(" "); + } + + private void setListFile() { + if (getFileViewList()) { + result.setVisibility(Component.HIDE); + listview.setVisibility(Component.VISIBLE); + fileProvider.notifyDataChanged(); + } else { + result.setVisibility(Component.VISIBLE); + listview.setVisibility(Component.HIDE); + } + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java new file mode 100755 index 0000000000000000000000000000000000000000..7cf3521657d5832bb88125416f93876246ffb7fa --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.ui; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.ListContainer; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.distributedschedule.interwork.DeviceManager; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.data.DeviceData; +import ohos.samples.distributedsearch.provider.DeviceDataProvider; +import ohos.samples.distributedsearch.utils.LogUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * The type Device select dialog. + * + * @since 2021-04-27 + */ +public class DeviceSelectDialog extends CommonDialog { + private static final String TAG = DeviceSelectDialog.class.getSimpleName(); + + private static final int CORNER_RADIUS = 10; + + private final AbilitySlice context; + + private DeviceInfo checkedDevice; + + /** + * Instantiates a new Device select dialog. + * + * @param context the context + */ + public DeviceSelectDialog(AbilitySlice context) { + super(context); + this.context = context; + } + + @Override + protected void onCreate() { + super.onCreate(); + // 1 Initialize device information + List deviceList = initDeviceData(); + // 2 Set data for listcontainer + Component rootView = + LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_layout_device, null, false); + ListContainer listContainer = + (ListContainer) rootView.findComponentById(ResourceTable.Id_list_container_device); + setItemProvider(listContainer, deviceList); + // 3 Set the yes or no event + configChoiceButton(rootView); + // 4 Set style + configStyle(rootView); + } + + private List initDeviceData() { + LogUtil.info(TAG, "begin to initDeviceData"); + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + List deviceList = new ArrayList<>(); + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceList.add(new DeviceData(false, deviceInfo)); + } + if (deviceInfoList.size() > 0) { + checkedDevice = deviceInfoList.get(0); + } + LogUtil.info(TAG, "get " + deviceInfoList.size() + " devices"); + return deviceList; + } + + private void setItemProvider(ListContainer listContainer, List deviceList) { + LogUtil.info(TAG, "begin to setItemProvider"); + DeviceDataProvider deviceDataProvider = + new DeviceDataProvider(context, deviceList, ResourceTable.Layout_dialog_device_item); + listContainer.setItemProvider(deviceDataProvider); + } + + private void configChoiceButton(Component rootView) { + LogUtil.info(TAG, "begin to configChoiceButton"); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_operate_yes); + operateYes.setClickedListener(component -> destroy()); + Text operateNo = (Text) rootView.findComponentById(ResourceTable.Id_operate_no); + operateNo.setClickedListener(component -> destroy()); + } + + private void configStyle(Component rootView) { + LogUtil.info(TAG, "begin to configStyle"); + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.BOTTOM); + setCornerRadius(CORNER_RADIUS); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java new file mode 100755 index 0000000000000000000000000000000000000000..57e05c1a66496a787ba9d7210b94f2dbd441b6cf --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.ui; + +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.utils.LogUtil; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +public class PopupDialog extends CommonDialog { + private static final String TAG = "PopupDialog"; + private static final int CORNER_RADIUS = 40; + private final Context mContext; + + public PopupDialog(Context context) { + super(context); + mContext = context; + } + @Override + protected void onCreate() { + super.onCreate(); + Component rootView = + LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_dialog_delete, null, false); + configChoiceButton(rootView); + configStyle(rootView); + } + private void configChoiceButton(Component rootView) { + LogUtil.info(TAG, "begin to configChoiceButton"); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_operate_yes); + operateYes.setClickedListener(component -> { + // delete file + destroy(); + }); + Text operateNo = (Text) rootView.findComponentById(ResourceTable.Id_operate_no); + operateNo.setClickedListener(component -> destroy()); + } + private void configStyle(Component rootView) { + LogUtil.info(TAG, "begin to configStyle"); + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.CENTER); + setCornerRadius(CORNER_RADIUS); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DeviceUtils.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DeviceUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..3e1310dc6270b2fbf53ded9c2cbace2b4288efa7 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DeviceUtils.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import ohos.account.AccountAbility; +import ohos.account.DistributedInfo; +import ohos.app.Context; +import ohos.data.distributed.common.KvManagerConfig; +import ohos.data.distributed.common.KvManagerFactory; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.distributedschedule.interwork.DeviceManager; +import java.util.ArrayList; +import java.util.List; + +public class DeviceUtils { + private static final String TAG = DeviceUtils.class.getSimpleName(); + + public static final int DEVICE_TYPE_NAME = 0; + public static final int DEVICE_TYPE_ID = 1; + + + private DeviceUtils() {} + + /** + * Get group id. + * @return group id. + */ + public static String getGroupId() { + AccountAbility account = AccountAbility.getAccountAbility(); + DistributedInfo distributeInfo = account.queryOsAccountDistributedInfo(); + return distributeInfo.getId(); + } + + public static List getAvailableDeviceId() { + List deviceIds = new ArrayList<>(); + + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + if (deviceInfoList == null) { + return deviceIds; + } + + if (deviceInfoList.size() == 0) { + System.out.println("did not find other device"); + return deviceIds; + } + + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceIds.add(deviceInfo.getDeviceId()); + } + + return deviceIds; + } + + /** + * Get available id + * @return available device ids + */ + public static List getAllAvailableDeviceId() { + List deviceIds = new ArrayList<>(); + + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ALL_DEVICE); + if (deviceInfoList == null) { + return deviceIds; + } + System.out.println("deviceInfoList size " + deviceInfoList.size()); + if (deviceInfoList.size() == 0) { + System.out.println("did not find other device"); + return deviceIds; + } + + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceIds.add(deviceInfo.getDeviceId()); + } + + return deviceIds; + } + + /** + * Check wether is the local device + * params: context: ability context + * info device name or id + * type: info type, 0 -- name, 1 -- id + * @return Remote device info list. + */ + public static boolean isLocalDevice(Context context, String info, int type) { + String result; + if (type == 0) { + result = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getName(); + } else if (type == 1) { + result = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getId(); + } else { + return false; + } + LogUtil.info(TAG, "info : "+info+",result : "+result); + return info.equals(result); + } + + /** + * Get remote device info + * @return Remote device info list. + */ + public static List getRemoteDevice() { + return DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java new file mode 100755 index 0000000000000000000000000000000000000000..519f0b9a4c77bf95e9cf25ef67ea64a21f57da31 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import ohos.aafwk.ability.DataAbilityHelper; +import ohos.aafwk.ability.DataAbilityRemoteException; + +import ohos.app.Context; +import ohos.data.distributed.common.KvManagerConfig; +import ohos.data.distributed.common.KvManagerFactory; +import ohos.data.resultset.ResultSet; +import ohos.media.photokit.metadata.AVStorage; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.utils.net.Uri; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +public class DistributedFile extends Thread{ + private static final String TAG = DistributedFile.class.getSimpleName(); + + public static final int FILE_TYPE_IMAGE = 0; + public static final int FILE_TYPE_AUDIO = 1; + public static final int FILE_TYPE_VIDEO = 2; + public static final int FILE_TYPE_TEXT = 3; + public static final int FILE_TYPE_FILE = 4; + public static final int FILE_TYPE_UNKNOWN = 0xFF; + + private static final int CACHE_SIZE = 8 * 1024; + private static final int END_OF_FILE = -1; + + private final String[] gImageType = {"jpg", "bmp", "jpeg", "png"}; + private final String[] gAudioType = {"mp3","wav", "flac"}; + private final String[] gVideoType = {"mp4","mjpeg"}; + private final String[] gTextType = {"xml","xlsx", "doc", "docx", "pdf", "txt"}; + + private final Context mContext; + private boolean isSearching = false; + private boolean checkResult = false; + + private final ArrayList localList = new ArrayList<>(); // Local file list object + private final ArrayList distributedList = new ArrayList<>(); // Distributed file list object + + public DistributedFile(Context context) { + mContext = context; + } + + @Override + public void run() { + isSearching = true; + initDistributedFiles(); // Initialize distributed file and local file list + getDistributedFiles(); // Get distributed file list + isSearching = false; + checkResult = true; + } + + public boolean isSearching() { + return isSearching; + } + + public boolean hasCheckResult() { + return checkResult; + } + + public List getFile(int type) { + if (distributedList.size() > 0) { + return getFileList(distributedList, type); + } else { + return getFileList(localList, type); + } + } + + private List getFileList(List gList, int type) { + if (type == FILE_TYPE_FILE || gList.size() == 0) { + return gList; + } + + ArrayList list = new ArrayList<>(); + + for (String filename : gList) { + if (isTypeFile(filename, type)) { + list.add(filename); + } + } + + return list; + } + + // Judge whether the file is the corresponding file type + private boolean isTypeFile(String file, int type) { + if (type == FILE_TYPE_FILE) { + return true; + } + if (type == FILE_TYPE_IMAGE) { + return isDestFile(file, gImageType); + } + if (type == FILE_TYPE_AUDIO) { + return isDestFile(file, gAudioType); + } + if (type == FILE_TYPE_VIDEO) { + return isDestFile(file, gVideoType); + } + if (type == FILE_TYPE_TEXT) { + return isDestFile(file, gTextType); + } + + return false; + } + + // Determines whether the string is in the given string array + private boolean isDestFile(String file, String[] des) { + int idx = file.lastIndexOf('.'); + if (idx < 0) { + return false; + } + String suffix = file.substring(idx+1); + + for (String de : des) { + if (de.equals(suffix)) { + return true; + } + } + + return false; + } + + // Search all local file entries + private void initDistributedFiles() { + // Search all pictures + searchFiles(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI); + // Search all audio files + searchFiles(AVStorage.Audio.Media.EXTERNAL_DATA_ABILITY_URI); + // Search all video files + searchFiles(AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI); + } + + // func: Obtain the corresponding data in the database through the URI and write it to the + // distributed file system + // param: uri -- A connection in a database to find data + private void searchFiles(Uri uri) { + // Gets the current database object + DataAbilityHelper helper = DataAbilityHelper.creator(mContext); + // Database column key fields + String[] projections = new String[]{AVStorage.AVBaseColumns.ID, AVStorage.AVBaseColumns.DISPLAY_NAME, AVStorage.AVBaseColumns.DATA}; + try { + // Get the database result object according to the URI provided + ResultSet resultSet = helper.query(uri, projections, null); + if (resultSet == null) { + LogUtil.info(TAG, "resultSet == null"); + return; + } + // Get database data + while (resultSet.goToNextRow()) { + int mediaId = resultSet.getInt(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.ID)); + // Get file name from database DATA column + String fullFileName = resultSet.getString(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.DATA)); + String fileName = fullFileName.substring(fullFileName.lastIndexOf(File.separator) + 1); + Uri tmpUri = Uri.appendEncodedPathToUri(uri, "" + mediaId); + writeToDistributedDir(mContext, helper, fileName, tmpUri); + localList.add(fileName); + } + } catch (DataAbilityRemoteException e) { + LogUtil.error(TAG, "query Files failed."); + } + + } + + // Writes local database files to the distributed file system + private void writeToDistributedDir(Context context, DataAbilityHelper helper, String fileName, Uri uri) { + // Determine whether the distributed file system path can be obtained normally + if (context.getDistributedDir() == null) { + WidgetHelper.showOneSecondTips(context, context.getString(ResourceTable.String_distributed_exception_info)); + return; + } + // Gets the device name of the current device + String deviceName = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getName(); + // The files currently added to the distributed system are prefixed with the device name to + // distinguish the same file name of different devices + String uniqueFileName = deviceName + "+" + fileName; + String distributedFilePath = context.getDistributedDir().getPath() + '/' + uniqueFileName; + + writeFile(distributedFilePath, helper, uri); + } + + private void writeFile(String filename, DataAbilityHelper helper, Uri uri) { + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + FileDescriptor fileDescriptor = helper.openFile(uri, "r"); + File file = new File(filename); + inputStream = new FileInputStream(fileDescriptor); + outputStream = new FileOutputStream(file); + + byte[] buffer = new byte[CACHE_SIZE]; + int count; + while ((count = inputStream.read(buffer)) != END_OF_FILE) { + outputStream.write(buffer, 0, count); + } + } catch (DataAbilityRemoteException | IOException e) { + LogUtil.error(TAG, "writeToDistributedDir exception : " + e); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (IOException e) { + LogUtil.error(TAG, "close stream io exception"); + } + } + } + + // Get distributed file list + private void getDistributedFiles() { + if (mContext.getDistributedDir() == null) { + WidgetHelper.showOneSecondTips(mContext, mContext.getString(ResourceTable.String_distributed_exception_info)); + return; + } + File file = new File(mContext.getDistributedDir().getPath()); + File[] files = file.listFiles(); + if (files == null) { + LogUtil.error(TAG, "no distributed files!"); + return; + } + + for (File eachFile : files) { + distributedList.add(eachFile.getPath()); + } + } + + // Obtain the corresponding file type according to the given file name + public int checkFileType(String filename) { + if(isDestFile(filename, gImageType)) { + return FILE_TYPE_IMAGE; + } + if (isDestFile(filename, gAudioType)) { + return FILE_TYPE_AUDIO; + } + if (isDestFile(filename, gVideoType)) { + return FILE_TYPE_VIDEO; + } + if (isDestFile(filename, gTextType)) { + return FILE_TYPE_TEXT; + } + + return FILE_TYPE_UNKNOWN; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java new file mode 100755 index 0000000000000000000000000000000000000000..2dfe183749f23c758e8026c9e3b76d7fc01a2f23 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.Locale; + +/** + * Log util function + * + * @since 2019-10-15 + */ +public class LogUtil { + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, ""); + + private static final String LOG_FORMAT = "%{public}s: %{public}s"; + + private LogUtil() { + /* Do nothing */ + } + + /** + * print device info to log + * + * @param className The prefix to log + * @param device The device into to print + * @param msg log message + */ + public static void printDevice(String className, DeviceInfo device, String msg) { + if (device == null) { + HiLog.error(LABEL_LOG, LOG_FORMAT, className, "DeviceInfo is null"); + } else { + HiLog.info(LABEL_LOG, + "%{public}s: %{public}s: { deviceId: %{public}s, deviceName: %{public}s, deviceType: %{public}s }", + className, msg, device.getDeviceId(), device.getDeviceName(), device.getDeviceType()); + } + } + + /** + * Print debug log + * + * @param className class name + * @param msg log message + */ + public static void debug(String className, String msg) { + HiLog.debug(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print info log + * + * @param className class name + * @param msg log message + */ + public static void info(String className, String msg) { + HiLog.info(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print info log + * + * @param className class name + * @param format format + * @param args args + */ + public static void info(String className, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, className, buffMsg); + } + + /** + * Print error log + * + * @param className class name + * @param msg log message + */ + public static void warn(String className, String msg) { + HiLog.warn(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print error log + * + * @param className class name + * @param msg log message + */ + public static void error(String className, String msg) { + HiLog.error(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print debug log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void debug(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.debug(LABEL_LOG, LOG_FORMAT, classType == null ? "null" : classType.getSimpleName(), buffMsg); + } + + /** + * Print info log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void info(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, classType == null ? "null" : classType.getSimpleName(), buffMsg); + } + + /** + * Print warn log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void warn(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.warn(LABEL_LOG, LOG_FORMAT, classType == null ? "null" : classType.getSimpleName(), buffMsg); + } + + /** + * Print error log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void error(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, classType == null ? "null" : classType.getSimpleName(), buffMsg); + } + + /** + * Print error log + * + * @param tag log tag + * @param format format + * @param args args + */ + public static void error(String tag, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java new file mode 100755 index 0000000000000000000000000000000000000000..0df69fd5ded883334528041fa65be7cc9ea63e69 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +import ohos.agp.colors.RgbColor; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.DirectionalLayout; +import ohos.agp.components.Text; +import ohos.agp.components.element.ShapeElement; +import ohos.agp.utils.Color; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.utils.TextAlignment; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; +import ohos.global.resource.NotExistException; +import ohos.global.resource.ResourceManager; +import ohos.global.resource.WrongTypeException; + +import java.io.IOException; + +/** + * The type Widget helper. + * + * @since 2021-04-27 + */ +public class WidgetHelper { + private static final String TAG = WidgetHelper.class.getSimpleName(); + + private static final int ONE_SECOND = 1000; + + private WidgetHelper() { + } + + /** + * Show tips. + * + * @param context the context + * @param msgId the msg id + */ + public static void showTips(Context context, int msgId) { + String msg = getStringByResourceId(context, msgId); + showOneSecondTips(context, msg); + } + + /** + * Show tips. + * + * @param context the context + * @param msg the msg + * @param durationTime the duration time + * @param widgetStyle the widget style + */ + public static void showTips(Context context, String msg, int durationTime, WidgetStyle widgetStyle) { + Text text = new Text(context); + text.setWidth(MATCH_CONTENT); + text.setHeight(MATCH_CONTENT); + text.setTextSize(widgetStyle.getTextSize()); + text.setText(msg); + text.setPadding(widgetStyle.getTextHorizontalPadding(), widgetStyle.getTextVerticalPadding(), + widgetStyle.getTextHorizontalPadding(), widgetStyle.getTextVerticalPadding()); + text.setMultipleLine(true); + text.setTextColor(Color.WHITE); + text.setTextAlignment(TextAlignment.CENTER); + + ShapeElement style = new ShapeElement(); + style.setShape(ShapeElement.RECTANGLE); + style.setRgbColor(new RgbColor(widgetStyle.getRgbColor())); + style.setCornerRadius(widgetStyle.getCornerRadius()); + text.setBackground(style); + + DirectionalLayout mainLayout = new DirectionalLayout(context); + mainLayout.setWidth(MATCH_PARENT); + mainLayout.setHeight(MATCH_CONTENT); + mainLayout.setAlignment(LayoutAlignment.CENTER); + mainLayout.addComponent(text); + + ToastDialog toastDialog = new ToastDialog(context); + toastDialog.setSize(MATCH_PARENT, MATCH_CONTENT); + toastDialog.setDuration(durationTime); + toastDialog.setAutoClosable(true); + toastDialog.setTransparent(true); + toastDialog.setAlignment(LayoutAlignment.CENTER); + toastDialog.setComponent((ComponentContainer) mainLayout); + toastDialog.show(); + } + + /** + * Show tips. + * + * @param context the context + * @param msg the msg + * @param durationTime the duration time + */ + public static void showTips(Context context, String msg, int durationTime) { + WidgetStyle widgetStyle = WidgetStyle.getDefault(); + showTips(context, msg, durationTime, widgetStyle); + } + + /** + * Show one second tips. + * + * @param context the context + * @param msg the msg + */ + public static void showOneSecondTips(Context context, String msg) { + showTips(context, msg, ONE_SECOND); + } + + /** + * Gets string by resource id. + * + * @param context the context + * @param id the id + * @return the string by resource id + */ + public static String getStringByResourceId(Context context, int id) { + if (context == null) { + LogUtil.info(TAG, "Context is null, getString failed"); + return ""; + } + ResourceManager resMgr = context.getResourceManager(); + if (resMgr == null) { + LogUtil.info(TAG, "ResourceManager is null, getString failed"); + return ""; + } + + String value = ""; + try { + value = resMgr.getElement(id).getString(); + } catch (NotExistException | WrongTypeException | IOException e) { + LogUtil.info(TAG, "get string value from resource manager failed"); + } + return value; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetStyle.java b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetStyle.java new file mode 100755 index 0000000000000000000000000000000000000000..ff8a120c96d5ad13d2c3024ecdf296d2ae30388e --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetStyle.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +/** + * The type Widget style. + * + * @since 2021-04-27 + */ +public class WidgetStyle { + private static final int DEFAULT_CORNER_RADIUS = 15; + + private static final int DEFAULT_TEXT_SIZE = 48; + + private static final int DEFAULT_H_PADDING = 30; + + private static final int DEFAULT_V_PADDING = 20; + + private static final int DEFAULT_RGB_COLOR = 0x666666FF; + + private int cornerRadius; + + private int textSize; + + // left and right padding + private int textHorizontalPadding; + + // top and bottom padding + private int textVerticalPadding; + + private int rgbColor; + + public int getCornerRadius() { + return cornerRadius; + } + + public void setCornerRadius(int cornerRadius) { + this.cornerRadius = cornerRadius; + } + + public int getTextSize() { + return textSize; + } + + public void setTextSize(int textSize) { + this.textSize = textSize; + } + + public int getTextHorizontalPadding() { + return textHorizontalPadding; + } + + public void setTextHorizontalPadding(int textHorizontalPadding) { + this.textHorizontalPadding = textHorizontalPadding; + } + + public int getTextVerticalPadding() { + return textVerticalPadding; + } + + public void setTextVerticalPadding(int textVerticalPadding) { + this.textVerticalPadding = textVerticalPadding; + } + + public int getRgbColor() { + return rgbColor; + } + + public void setRgbColor(int rgbColor) { + this.rgbColor = rgbColor; + } + + /** + * Gets default. + * + * @return the default + */ + public static WidgetStyle getDefault() { + WidgetStyle widgetStyle = new WidgetStyle(); + widgetStyle.setCornerRadius(DEFAULT_CORNER_RADIUS); + widgetStyle.setTextSize(DEFAULT_TEXT_SIZE); + widgetStyle.setTextHorizontalPadding(DEFAULT_H_PADDING); + widgetStyle.setTextVerticalPadding(DEFAULT_V_PADDING); + widgetStyle.setRgbColor(DEFAULT_RGB_COLOR); + return widgetStyle; + } +} diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml new file mode 100755 index 0000000000000000000000000000000000000000..10b8c664355dad4884b31086c69338890ca7be53 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/colors.json b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/colors.json new file mode 100755 index 0000000000000000000000000000000000000000..c01a9178b72ed93c04ae6695182169ce1bbb7b21 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/colors.json @@ -0,0 +1,20 @@ +{ + "color": [ + { + "name": "news_type_text_off", + "value": "#55000000" + }, + { + "name": "news_type_text_on", + "value": "#afaafa" + }, + { + "name": "white", + "value": "#ffffff" + }, + { + "name": "half_transparent", + "value": "#55000000" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/string.json b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..723ac761ff2d1bd104629e0c875b14695bc9bdcc --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/element/string.json @@ -0,0 +1,88 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "DistributedSearch" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "Hello World" + }, + { + "name": "button_distributed_device", + "value": "Dev" + }, + { + "name": "button_add_distributed", + "value": "Join distributed file system" + }, + { + "name": "image_label", + "value": "Image" + }, + { + "name": "audio_label", + "value": "Audio" + }, + { + "name": "video_label", + "value": "Video" + }, + { + "name": "text_label", + "value": "File" + }, + { + "name": "all_label", + "value": "All" + }, + { + "name": "result_info_label", + "value": "No results" + }, + { + "name": "cancel_label", + "value": "Cancel" + }, + { + "name": "confirm_label", + "value": "Confirm" + }, + { + "name": "input_notice_msg", + "value": "Please enter a valid search keyword" + }, + { + "name": "file_path_label", + "value": "File path" + }, + { + "name": "local_device_name", + "value": "Local" + }, + { + "name": "distributed_exception_info", + "value": "Note: distributed file exception!" + }, + { + "name": "file_source_label", + "value": "File source" + }, + { + "name": "delete_file_info", + "value": "Are you sure to delete this file?" + }, + { + "name": "delete_file_warn", + "value": "The file cannot be recovered after deletion" + }, + { + "name": "delete_label", + "value": "Delete" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100755 index 0000000000000000000000000000000000000000..bf57e7d9597c110a224c151305e542eb1c8f837a --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml new file mode 100755 index 0000000000000000000000000000000000000000..56ca85398820664931a328cfe2ef4035270467bd --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml new file mode 100755 index 0000000000000000000000000000000000000000..fc5145eada206c296a79f54953556e8ffb18cbc8 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml new file mode 100755 index 0000000000000000000000000000000000000000..f1ee87e0d4328ad778971b007a9d0e249a883223 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml new file mode 100755 index 0000000000000000000000000000000000000000..d67d9854176ac7a171355d6e8eb46c612b9bb452 --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml new file mode 100755 index 0000000000000000000000000000000000000000..214ff957da31faa59e5544373c66750bebfd5c3e --- /dev/null +++ b/ScenarioDemos/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/confignet/index.js b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/confignet/index.js new file mode 100755 index 0000000000000000000000000000000000000000..da84c7e1a94a092df7a082d71bfabe7b32f0b4c6 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/confignet/index.js @@ -0,0 +1,85 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + oldWifi:"", + wifiName:"", + wifiPassword:"", + NetworkFlag: false, + text:'' + }, + onInit() { + this.text = this.$t('strings.buttonOk'), + this.wifiName = this.oldWifi; + }, + + // goto locationset page. + goBack() { + router.push({ + uri: "pages/phone/index" + }) + }, + + // Call find Device interface. + goNext() { + let that = this; + this.NetworkFlag = true; + let wifiName = this.wifiName; + + let data = {}; + data.cmd = 0x20; + let param ={}; + param.wifiName = this.wifiName; + param.wifiPassword = this.wifiPassword; + data.param = param; + let toastConfigNetError = this.$t("strings").configNetError; + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.SET_WIFI_CODE).then(function(res){ + let result = JSON.parse(res); + if (result.code == 200) { + // get serverip + let serverIp = ""; + router.push({ + uri: "pages/locationset/index", + params: { + serverIp: result.result.ip, + wifiName: wifiName + } + }) + } else { + prompt.showToast({ + message: toastConfigNetError + result.errmsg + }); + that.NetworkFlag = false; + } + }); + }, + changeWifiName(e){ + this.wifiName = e.value; + }, + changeWifiPassword(e){ + this.wifiPassword = e.value; + }, + useOtherNet(){ + router.push({ + uri: "pages/otherWifi/index", + }) + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.css b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.css new file mode 100755 index 0000000000000000000000000000000000000000..a159433fce84990149ed19ce1192d20f3103c3f5 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.css @@ -0,0 +1,22 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.imageux{ + margin-right: 20px; + width: 60px; + height:60px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.hml b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..ebc2df64ebc8f15c47badbb60b5d3878142e8cfc --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.hml @@ -0,0 +1,35 @@ + + + +
+
+ + {{$t('strings.versionNum')}} + {{$t('strings.authorizeDescription')}} + +
+ + {{$t('strings.login')}} +
+
+ {{$t('strings.cancle')}} +
+
+ {{$t('strings.determine')}} + {{$t('strings.privacyStatement')}} +
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.js b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.js new file mode 100755 index 0000000000000000000000000000000000000000..c891ad4cb7dcc0a42a20eddd62a69da75cbd9644 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/index/index.js @@ -0,0 +1,36 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from "@system.router" +import app from '@system.app'; +export default { + data: { + + }, + onInit() { + }, + + // Goto phone page. + goNext() { + router.push({ + uri: "pages/phone/index" + }) + }, + + // Exit the current ability. + goBack() { + app.terminate(); + } +} diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.css b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.css new file mode 100755 index 0000000000000000000000000000000000000000..84d913bd690e93240b67c357e4fe67366fa407ef --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.css @@ -0,0 +1,42 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.rightsrcux{ + width: 15px; + height: 27px; + margin-top: 10px; +} + +.homeux{ + margin-left: 32px; + margin-right: 32px; + justify-content: space-around; + margin-top: 48px; + flex-wrap: wrap; + margin-bottom: 48px; +} + +.homeitemux{ + font-weight: 500; + font-size: 24px; + width:138px; + height: 50px; + margin-top: 20px; + text-color:#000000; + margin-right:2px; + +} diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.hml b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..50d7acd8f335c0d93e296d3b08bf558a65690441 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.hml @@ -0,0 +1,39 @@ + + + +
+ +
+ {{$t('strings.family')}} +
+ {{ + $t('strings.myHouse') }} + +
+ +
+
+
+ +
+
+ +
+ +
+ +
+
diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.js b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.js new file mode 100755 index 0000000000000000000000000000000000000000..7f1730efe8a25e9119c449fa444bd2d8f563f237 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/locationset/index.js @@ -0,0 +1,92 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router' +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + wifiName: "", + serverIp: "", + DeviceSettings: [{ + name: '', + backcolor: "rgba(0, 175, 255, 0.2)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }], + }, + onInit() { + this.DeviceSettings[0].name = this.$t('strings.livingRoom'); + this.DeviceSettings[1].name = this.$t('strings.bedroom'); + this.DeviceSettings[2].name = this.$t('strings.secondBedroom'); + this.DeviceSettings[3].name = this.$t('strings.restaurant'); + + this.DeviceSettings[4].name = this.$t('strings.study'); + this.DeviceSettings[5].name = this.$t('strings.Restroom'); + this.DeviceSettings[6].name = this.$t('strings.bathroom'); + this.DeviceSettings[7].name = this.$t('strings.balcony'); + }, + + // Goback to confignet page. + goBack() { + app.terminate(); + }, + + // Config network successfully entered the control page,and pass parameter:sessionId. + goNext() { + console.info("aaaaa:"+ this.serverIp); + let data = {}; + let wifiName = this.wifiName; + let ToastMes= this.$t('strings.connectBackInfo') + wifiName; + let serverIp = this.serverIp; + let faSoftapUtil = this.$app.$def.faSoftapUtil; + + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function(res){ + if (res == wifiName) { + let info = { + serverIp: serverIp + } + faSoftapUtil.callNewFa(info,0); + app.terminate(); + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.css b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.css new file mode 100755 index 0000000000000000000000000000000000000000..dfa95094914df428f3dde427cae22abe7016035f --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.css @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +@import '../../common/css/common.css'; + +.container { + flex-direction: column; + justify-content: center; + padding-top: 30px; + margin: 0 82px; +} + +.title { + font-size: 42px; +} + +.subtitle { + margin: 20px 0px; + font-size: 24px; + opacity: .8; +} + +.list { +} + +.list-item { + height: 124px; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #000000; + +} + +.list-text-box { + flex-direction: column; + justify-content: center; +} + +.ssid { + font-size: 32px; +} + +.tag { + font-size: 28px; + padding-top: 10px; + opacity: .8; +} + +.right-image { + width: 48px; + height: 48px; +} +.cancel{ + margin-bottom: 50px; +} + + diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.hml b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..98b88fef543ba4a053b20fc355c077c5482f0d11 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.hml @@ -0,0 +1,36 @@ + + +
+ + 使用其他无线网络 + + + 已为您提供设备支持的WLAN网络 + + + + +
+ {{ $item.ssid }} + {{ $item.security }} +
+ +
+
+
+ +
+ diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.js b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.js new file mode 100755 index 0000000000000000000000000000000000000000..ce59d4fc83a52fbac54c0385fcb114b4b101c15f --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/otherWifi/index.js @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router' +import prompt from '@system.prompt'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + wifiList: [] + }, + onInit() { + console.info("time control init") + }, + onShow() { + this.refreshList(); + }, + cancel() { + router.back(); + }, + clickItem(index) { + if (index == 0) { + router.back(); + } + else{ + router.push({ + uri: 'pages/confignet/index', + params: { + oldWifi: this.wifiList[index].ssid + } + }) + } + }, + refreshList(){ + let data = {}; + let that = this; + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_AVAILABLE_WIFI_CODE).then(function(res){ + let result = JSON.parse(res); + console.info("aaaaa " + res); + if (result.code == 200) { + // get serverip + that.wifiList = result.wifi; + } else { + prompt.showToast({ + message: result.errMsg + }); + } + }); + } +} diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.css b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.css new file mode 100755 index 0000000000000000000000000000000000000000..498079758640967b76c0e0685925b54e55853292 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.css @@ -0,0 +1,27 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.aboutsrcux{ + margin-left: 10px; + width: 35px; + height: 35px; +} + +.lightonsrcux{ + width: 50px; + height: 50px; +} diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.hml b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..e7cc9c6a520ef3d7b5a6180276a1d1884d2a3f09 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.hml @@ -0,0 +1,29 @@ + + + +
+ +
+ {{$t('strings.readytoconnectInfo')}} +
+
+ {{$t('strings.setWifi')}} +
+
+ + +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.js b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.js new file mode 100755 index 0000000000000000000000000000000000000000..e8d001435e4378ba6c1b86e7b4a85fcdd047492e --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/js/default/pages/phone/index.js @@ -0,0 +1,75 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + oldWifi: "" + }, + onInit: async function(){ + let data = {}; + let wifi = await this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE); + if (wifi != fan_constants.CONSTANTS.SMARTFAN_WIFI) { + this.oldWifi = wifi; // Record the wifi name before + } + }, + + /** + * Call isSupportWifiAware interface + * + * @return result.code + */ + onReady: function () { + }, + +// Support wifiware and goto confignet page. + goNext: function () { + let data = {}; + let wifi = this.oldWifi; + let ToastMes = this.$t('strings.notConnectHotSpot'); + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function (res) { + if (res == fan_constants.CONSTANTS.SMARTFAN_WIFI) { + router.push({ + uri: "pages/confignet/index", + params: { + oldWifi: wifi + } + }) + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, + + // Exit the current ability. + goBack() { + app.terminate(); + }, + async goSetWifi(){ + var action = {}; + action.bundleName = "com.android.settings"; + action.abilityName = "com.android.settings.Settings$WifiSettingsActivity"; + action.flag = 16; //Intent.FLAG_NOT_OHOS_COMPONENT + action.data = {}; + await FeatureAbility.startAbility(action); + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/element/string.json b/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..0c086f2ef955888e2fcba20ef770be4f193bc9d1 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/element/string.json @@ -0,0 +1,31 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能电风扇" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "sockcketability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/media/icon.png b/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/media/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..afa850c941c877272b96805e1a35ac2eafca0108 Binary files /dev/null and b/ScenarioDemos/SmartFanApp/entry/src/main/resources/base/media/icon.png differ diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/resources/en/element/string.json b/ScenarioDemos/SmartFanApp/entry/src/main/resources/en/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..4e017ff8223b1673c3955241762348e656c6b071 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/resources/en/element/string.json @@ -0,0 +1,31 @@ +{ + "string": [ + { + "name": "app_name", + "value": "SmartFan" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "sockcketability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "public" + }, { + "name": "encrypt", + "value": "encrypt" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/main/resources/zh/element/string.json b/ScenarioDemos/SmartFanApp/entry/src/main/resources/zh/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..0c086f2ef955888e2fcba20ef770be4f193bc9d1 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,31 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能电风扇" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "sockcketability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/ohosTest/java/ohos/samples/smartfan/ExampleOhosTest.java b/ScenarioDemos/SmartFanApp/entry/src/ohosTest/java/ohos/samples/smartfan/ExampleOhosTest.java new file mode 100755 index 0000000000000000000000000000000000000000..c11beef1f91171de257a80e5b6bfab8ec86bac25 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/ohosTest/java/ohos/samples/smartfan/ExampleOhosTest.java @@ -0,0 +1,14 @@ +package ohos.samples.smartfan; + +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + assertEquals("ohos.samples.smartfan", actualBundleName); + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanApp/entry/src/test/java/ohos/samples/smartfan/ExampleTest.java b/ScenarioDemos/SmartFanApp/entry/src/test/java/ohos/samples/smartfan/ExampleTest.java new file mode 100755 index 0000000000000000000000000000000000000000..45457e61fb0ce75595b5b437235c996f86b61521 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/entry/src/test/java/ohos/samples/smartfan/ExampleTest.java @@ -0,0 +1,9 @@ +package ohos.samples.smartfan; + +import org.junit.Test; + +public class ExampleTest { + @Test + public void onStart() { + } +} diff --git a/ScenarioDemos/SmartFanApp/screenshoot/phone/fan_control.png b/ScenarioDemos/SmartFanApp/screenshoot/phone/fan_control.png new file mode 100755 index 0000000000000000000000000000000000000000..d39c61cf6cd81509a1b65331496473b5e4493255 Binary files /dev/null and b/ScenarioDemos/SmartFanApp/screenshoot/phone/fan_control.png differ diff --git a/ScenarioDemos/SmartFanApp/settings.gradle b/ScenarioDemos/SmartFanApp/settings.gradle new file mode 100755 index 0000000000000000000000000000000000000000..28d595f2fba0d06b2025da200383d15f87c4e9f0 --- /dev/null +++ b/ScenarioDemos/SmartFanApp/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ScenarioDemos/SmartFanDevice/README_zh.md b/ScenarioDemos/SmartFanDevice/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..477cd24c757bc0c99bacae88a0bad2df2647444b --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/README_zh.md @@ -0,0 +1,62 @@ +# 智能风扇设备端代码介绍 + +### 简介 + +本Sample是基于OpenHarmony轻量级系统,利用内核的实时性和丰富的外设拓展功能,模拟智能风扇设备跟手机FA通信,实现风扇开关,档位,模式以及按温按时控制等功能。 + + + +### 使用说明 + +##### 1. 编译步骤 + +1)拷贝本Sample目录下的common、smartfan 文件夹到OpenHarmony 系统源码中的applications/sample/wifi-iot/app目录下。 + +2) 修改applications/sample/wifi-iot/app/BUILD.gn 文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,具体配置如下。 + +``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "smartfan", + ] + deps = [ "//applications/sample/wifi-iot/app/common/hals:hals" ] +} + +``` + +3)修改hi3861 内核配置文件 + +​ 打开 device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk 文件 + +​ 将 CONFIG_I2C_SUPPORT is not set这一行, 改为CONFIG_I2C_SUPPORT=y + +​ 将 CONFIG_PWM_SUPPORT is not set这一行, 改为CONFIG_PWM_SUPPORT=y + +4) 代码编译和烧录请参考:[链接](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-connection.md) + +##### 2. 与手机应用联动 + +1)准备一个wifi热点A,密码和热点名称自定义。 + +2)提前在手机上安装好智能风扇手机端软件,然后在设置应用中连接热点A。 + +3) 打开手机端智能风扇软件,在热点连接列表中找到SmartFan_AP热点并连接,随后点击配网发送热点A相关信息给到风扇设备端完成配网。 + +4)待配网完成后,可以在手机端自由设置风扇的工作状态和相应模式。 + + + +### 约束限制 + +硬件:HiSpark Wi-Fi IoT 开发套件(本sample会用到 主控板、OLED拓展板、温度传感器拓展板) + +软件:OpenHarmony 2.0 Canary版本。[链接](https://device.harmonyos.com/cn/docs/start/get-code/sourcecode-acquire-0000001050769927) + +OpenHarmony轻量级开发指导:[链接](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-lite-overview-0000001105598722) + +开发工具下载:[链接](https://device.harmnyos.com/cn/ide) + + + diff --git a/ScenarioDemos/SmartFanDevice/common/hals/BUILD.gn b/ScenarioDemos/SmartFanDevice/common/hals/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..fbd1f3af0b4116443be7893f2c005ab0e30639e8 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/hals/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("hals") { + sources = [ + "src/peripheral_hal.c", + "src/utils_hal.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include", + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/hals/src/peripheral_hal.c b/ScenarioDemos/SmartFanDevice/common/hals/src/peripheral_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..6a106ad539426024439a0d3576dbd02d0f26b5ce --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/hals/src/peripheral_hal.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "peripheral_hal.h" +#include "iot_errno.h" +#include "hi_io.h" +#include "hi_adc.h" +#include "hi_types_base.h" +#include "hi_watchdog.h" +#include "hi_pwm.h" + +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val) +{ + if (id == HAL_WIFI_IOT_IO_NAME_MAX) { + return IOT_FAILURE; + } + return hi_io_set_func((hi_io_name)id, val); +} + +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt) +{ + return hi_adc_read((hi_adc_channel_index)channel, (hi_u16*)data, (hi_adc_equ_model_sel)equModel, + (hi_adc_cur_bais)curBais, (hi_u16)rstCnt); +} + +void HalSetWatchDogEnable(int enable) +{ + if (enable == 0) { + hi_watchdog_disable(); + } else { + hi_watchdog_enable(); + } +} + +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq) +{ + return hi_pwm_start((hi_pwm_port)id, (hi_u16)duty, (hi_u16)freq); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/hals/src/utils_hal.c b/ScenarioDemos/SmartFanDevice/common/hals/src/utils_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..47e517ab98eb1079eeff7b5fad9d8be8b255ef50 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/hals/src/utils_hal.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos_types.h" +#include "hi_time.h" +#include "hi_types_base.h" +#include "utils_hal.h" + +void hal_udelay(uint32 us) +{ + hi_udelay((hi_u32)us); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/include/common_log.h b/ScenarioDemos/SmartFanDevice/common/include/common_log.h new file mode 100755 index 0000000000000000000000000000000000000000..5c3aa9ea075dd0292fca44bb89573c9749bea943 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/include/common_log.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __COMMON_LOG_H__ +#define __COMMON_LOG_H__ + +#include + +#define LOG_D(fmt, args...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_I(fmt, args...) printf("[INFO][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_E(fmt, args...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) + +#endif // __COMMON_LOG_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/include/network_manager_service.h b/ScenarioDemos/SmartFanDevice/common/include/network_manager_service.h new file mode 100755 index 0000000000000000000000000000000000000000..c5a40932385fd87743506fcff85005b9a1307521 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/include/network_manager_service.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_MANAGER_SERVICE_H__ +#define __NETWORK_MANAGER_SERVICE_H__ + +typedef enum { + NET_EVENT_NULL, + NET_EVENT_CONFIG, // Config wifi + NET_EVENT_CONFIG_FAIL, // Config wifi failed + NET_EVENT_CONFIG_SUCC, // Config wifi success + NET_EVENT_CONNECTTING, // connectting wifi + NET_EVENT_CONN_FAILED, // connect wifi failed + NET_EVENT_CONNECTTED, // Wifi connected + NET_EVENT_DISCONNECT, // Wifi disconnected + NET_EVENT_RECV_DATA, // Recv message from FA + + NET_EVENT_TYPE_NBR +}NET_EVENT_TYPE; + +typedef enum { + NET_MODE_IDLE, // the idle mode + NET_MODE_CONFIG, // the netcfg in the AP mode + NET_MODE_STA, // the netcfg int the STA mode + + NET_MODE_NBR +}NET_MODE_TYPE; + +typedef enum { + NET_STA_NULL, + NET_STA_CONFIG, // Config wifi + NET_STA_CONNECTTING, // connectting wifi + NET_STA_CONNECTTED, // Wifi connected + NET_STA_DISCONNECT, // Wifi disconnected + + NET_STA_TYPE_NBR +}NET_STA_TYPE; + +/** + * @brief: the network config service callback + * + * @param event reference {@link NET_EVENT_TYPE} + * @param data The data of the event: NET_EVENT_RECV_DATA or NET_EVENT_SEND_DATA + * @since 1.0 + * @version 1.0 + */ +typedef int (*NetManagerEventCallback)(NET_EVENT_TYPE event, void *data); + +/** + * @brief Register the network config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The callback of netcfg module + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief Set the network mode. + * + * @param mode : the network module, reference {@NET_MODE_TYPE} + * @since 1.0 + * @version 1.0 + */ +void NetManagerSetNetMode(int mode); + +/** + * @brief Send msg to FA. + * + * @param msg : the msg to send + * @since 1.0 + * @version 1.0 + * + * @return 0 -- success, others -- failed + */ +int NetManagerSendMsg(const char *msg); + +/** + * @brief UnRegister the network config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetManagerDeinit(void); + +#endif // __NETWORK_MANAGER_SERVICE_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/include/peripheral_hal.h b/ScenarioDemos/SmartFanDevice/common/include/peripheral_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..536e804538cb97e54625ce3399b5e8697b9c14eb --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/include/peripheral_hal.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERIPHERAL_HAL_H +#define PERIPHERAL_HAL_H + +#include "ohos_types.h" + +/* gpio start */ +typedef enum { + /** GPIO hardware pin 0 */ + HAL_WIFI_IOT_IO_NAME_GPIO_0, + /** GPIO hardware pin 1 */ + HAL_WIFI_IOT_IO_NAME_GPIO_1, + /** GPIO hardware pin 2 */ + HAL_WIFI_IOT_IO_NAME_GPIO_2, + /** GPIO hardware pin 3 */ + HAL_WIFI_IOT_IO_NAME_GPIO_3, + /** GPIO hardware pin 4 */ + HAL_WIFI_IOT_IO_NAME_GPIO_4, + /** GPIO hardware pin 5 */ + HAL_WIFI_IOT_IO_NAME_GPIO_5, + /** GPIO hardware pin 6 */ + HAL_WIFI_IOT_IO_NAME_GPIO_6, + /** GPIO hardware pin 7 */ + HAL_WIFI_IOT_IO_NAME_GPIO_7, + /** GPIO hardware pin 8 */ + HAL_WIFI_IOT_IO_NAME_GPIO_8, + /** GPIO hardware pin 9 */ + HAL_WIFI_IOT_IO_NAME_GPIO_9, + /** GPIO hardware pin 10 */ + HAL_WIFI_IOT_IO_NAME_GPIO_10, + /** GPIO hardware pin 11 */ + HAL_WIFI_IOT_IO_NAME_GPIO_11, + /** GPIO hardware pin 12 */ + HAL_WIFI_IOT_IO_NAME_GPIO_12, + /** GPIO hardware pin 13 */ + HAL_WIFI_IOT_IO_NAME_GPIO_13, + /** GPIO hardware pin 14 */ + HAL_WIFI_IOT_IO_NAME_GPIO_14, + /** Maximum value */ + HAL_WIFI_IOT_IO_NAME_MAX, +} HalWifiIotIoName; + +/** + * @brief set IO function. + * + * @param id -- IO number, reference {@ HalWifiIotIoName}. + * @param val -- the io function value which defined in {@ hi_io.h}. + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val); +/* gpio end */ + + +/* adc start */ + +/** + * @brief Enumerates ADC channel indexes. + * + */ +typedef enum { + /** Channel 0 */ + HAL_WIFI_IOT_ADC_CHANNEL_0, + /** Channel 1 */ + HAL_WIFI_IOT_ADC_CHANNEL_1, + /** Channel 2 */ + HAL_WIFI_IOT_ADC_CHANNEL_2, + /** Channel 3 */ + HAL_WIFI_IOT_ADC_CHANNEL_3, + /** Channel 4 */ + HAL_WIFI_IOT_ADC_CHANNEL_4, + /** Channel 5 */ + HAL_WIFI_IOT_ADC_CHANNEL_5, + /** Channel 6 */ + HAL_WIFI_IOT_ADC_CHANNEL_6, + /** Channel 7 */ + HAL_WIFI_IOT_ADC_CHANNEL_7, + /** Button value */ + HAL_WIFI_IOT_ADC_CHANNEL_BUTT, +} HalWifiIotAdcChannelIndex; + +/** + * @brief Enumerates analog power control modes. + */ +typedef enum { + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_AUTO, + /** Manual control (AVDD = 1.8 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_1P8V, + /** Manual control (AVDD = 3.3 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_3P3V, + /** Button value */ + HAL_WIFI_IOT_ADC_CUR_BAIS_BUTT, +} HalWifiIotAdcCurBais; + +/** + * @brief Enumerates equation models. + */ +typedef enum { + /** One-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_1, + /** Two-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_2, + /** Four-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_4, + /** Eight-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_8, + /** Button value */ + HAL_WIFI_IOT_ADC_EQU_MODEL_BUTT, +} HalWifiIotAdcEquModelSel; + +/** + * @brief Reads a piece of sampled data from a specified ADC channel based on the input parameters. + * + * + * + * @param channel Indicates the ADC channel index. + * @param data Indicates the pointer to the address for storing the read data. + * @param equModel Indicates the equation model. + * @param curBais Indicates the analog power control mode. + * @param rstCnt Indicates the count of the time from reset to conversion start. + * One count is equal to 334 ns. The value must range from 0 to 0xFF0. + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt); +/** adc end ****/ + +/** + * @brief set WatchDog enable or disable. + * + * @param enable -- 1 enable, 0 disable. + * + * @since 1.0 + * @version 1.0 + */ +void HalSetWatchDogEnable(int enable); + +/** + * @brief start the pwm. + * + * @param id Port id of PWM + * @param duty The usefull cycles of PWM + * @param freq The total cycles of PWM + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq); + +#endif // PERIPHERAL_HAL_H \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/include/utils_hal.h b/ScenarioDemos/SmartFanDevice/common/include/utils_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..a64632197cfdabc66f17f863bc7fae0dce3040e3 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/include/utils_hal.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_HAL_H__ +#define __UTILS_HAL_H__ + +void hal_udelay(uint32 us); + +#endif // __UTILS_HAL_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/BUILD.gn b/ScenarioDemos/SmartFanDevice/common/netcfg/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..0f1f3827594a59b8440de8d089ea6380ee963f9b --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("netcfg") { + sources = [ + "src/network_config.c", + "src/network_server.c", + "src/network_manager_service.c", + "src/softap.c", + "src/wifi_sta.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/include/defines.h b/ScenarioDemos/SmartFanDevice/common/netcfg/include/defines.h new file mode 100755 index 0000000000000000000000000000000000000000..ea1ef6fd683fd632d6881419e258557720fbff92 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/include/defines.h @@ -0,0 +1,52 @@ + + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 +#define AP_NAME "HmosAP" + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#endif /* __DEFINES_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_config.h b/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_config.h new file mode 100755 index 0000000000000000000000000000000000000000..487e9931742f5151da674599c60b55ac4c4be391 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_config.h @@ -0,0 +1,67 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_CONFIG_H__ +#define __NETWORK_CONFIG_H__ + +#include "network_manager_service.h" + +#define NET_TASK_STACK_SIZE (1024*8) +#define NET_TASK_PRIO 31 + +/** + * @brief start net config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The NetEvent callback. event reference {@NET_EVENT_TYPE} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief stop net config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStop(void); + +/** + * @brief set net config mode + * @param mode -- reference {@NET_MODE_TYPE} + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgSetMode(int mode); + +/** + * @brief start connect the wifi + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStartConnect(const char *ssid, const char *pwd); + +#endif /* __NETWORK_CONFIG_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_server.h b/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_server.h new file mode 100755 index 0000000000000000000000000000000000000000..01f60012fa88cfd11228de84bd74396361c6bac0 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/include/network_server.h @@ -0,0 +1,87 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +#include "network_manager_service.h" + +#define NETSERVER_TASK_STACK_SIZE (1024*4) +#define NETSERVER_TASK_PRIO 33 + + +/** + * @brief start netserver task + * + * @param nEventCallback -- The NetEvent callback, + * when the server recv data, + * it will be called with (@NET_EVENT_RECV_DATA) + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerInit(NetManagerEventCallback nEventCallback); + +/** + * @brief stop netserver task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerDeinit(void); + +/** + * @brief set netserver task resume + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStart(void); + +/** + * @brief set netserver task suspend + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStop(void); + +/** + * @brief check the netserver when suspend or not. + * + * @since 1.0 + * @version 1.0 + * + * @return true -- netserver task is activity, false -- netserver is suspend + */ +bool NetServerIsRun(void); + +/** + * @brief send msg to client + * @param msg -- The message to send + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerSendMsg(const char *msg); + +#endif /* __NETWORK_SERVER_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/include/softap.h b/ScenarioDemos/SmartFanDevice/common/netcfg/include/softap.h new file mode 100755 index 0000000000000000000000000000000000000000..f27a8760dd5060da5d26c0ddea2eec1fc421d213 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/include/softap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SOFT_AP_H__ +#define __SOFT_AP_H__ + +/** + * @brief start ap mode. + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int SoftApStart(const char *ap_name); + +/** + * @brief stop ap mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void SoftApStop(void); + +#endif /* __SOFT_AP_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/include/wifi_sta.h b/ScenarioDemos/SmartFanDevice/common/netcfg/include/wifi_sta.h new file mode 100755 index 0000000000000000000000000000000000000000..84dabda37d4cbffb851b1ca03aafbf300631a101 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/include/wifi_sta.h @@ -0,0 +1,63 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_STA_H__ +#define __WIFI_STA_H__ + +#include "wifi_device.h" + +/** + * @brief wifi state change callback. + * @param state -- wifi state, 0 -- wifi not connect, 1 -- wifi connectted + * + * @since 1.0 + * @version 1.0 + * + */ +typedef void (*WifiChangeEvent)(int state); + +/** + * @brief start sta mode. + * @param WifiChange--wifi state changed callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaStart(WifiChangeEvent WifiChange); + +/** + * @brief start connect wifi. + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaConnect(const char *ssid, const char *pwd); + +/** + * @brief stop sta mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void WifiStaStop(void); + +#endif /* __WIFI_STA_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_config.c b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_config.c new file mode 100755 index 0000000000000000000000000000000000000000..de95133b10914d5cf46bd4d4fdca182362bdaefd --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_config.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "softap.h" +#include "wifi_sta.h" + +#include "network_config.h" +#include "network_server.h" +#include "defines.h" + +#define SSID_MAX_LEN 32 +#define PWD_MAX_LEN 32 + +#define NET_PORT 8686 + +#define RETRY_TIMES 5 +#define CONNECT_TIMEOUT 20 + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "wifiName" +#define PWD_KEY "wifiPassword" + +#define CMD_CONFIG 0x20 + +typedef struct { + NET_MODE_TYPE mode; + NET_STA_TYPE status; + bool netRun; + int timeCounts; + + NetManagerEventCallback gEventCall; +} NetManagerInfo; + +static NetManagerInfo g_netManager; +const char *g_apName = NULL; + +#define SET_NET_EVENT(s, e, d) ({ \ + if (g_netManager.gEventCall != NULL) { \ + g_netManager.gEventCall(e, d); \ + } \ + g_netManager.status = s; \ +}) + +static void NetCfgConnectStatus(int s) +{ + if (s == 1 && g_netManager.status != NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_CONNECTTED; + } else if (s == 0) { + if (g_netManager.status == NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_DISCONNECT; + } + g_netManager.mode = NET_MODE_IDLE; + } +} + +#define SHIFT_MASK 0xff +#define SHIFT_8BIT(a) (((a) >> 8) & (SHIFT_MASK)) +#define SHIFT_16BIT(a) (((a) >> 16) & (SHIFT_MASK)) +#define SHIFT_24BIT(a) (((a) >> 24) & (SHIFT_MASK)) + +static void GetIpString(uint32_t ip, char *ipAddr, int size) +{ + if (ipAddr == NULL || size <= 0) { + return; + } + + if (sprintf_s(ipAddr, size, "%d.%d.%d.%d", ip & SHIFT_MASK, SHIFT_8BIT(ip), SHIFT_16BIT(ip), SHIFT_24BIT(ip)) < 0) { + LOG_E("GetIpString failed! \n"); + } + LOG_D("ipAddr : %s \n", ipAddr); +} + +int DeviceGetIp(char *buff, int size) +{ + int ret; + long ip; + struct netif *netif_node = netif_find("wlan0"); + if (netif_node == NULL) { + LOG_E("GetLocalWifiIp netif get fail\r\n"); + return -1; + } + + ip4_addr_t ipAddr; + ip4_addr_t netMask; + ip4_addr_t gateWay; + + ret = netifapi_netif_get_addr(netif_node, &ipAddr, &netMask, &gateWay); + if (ret == 0) { + ip = ip4_addr_get_u32(&ipAddr); + GetIpString(ip, buff, size); + return 0; + } + return -1; +} + +static void SendLocalIp(int sockfd, int code) +{ + char ip[BUF_SHORT_SIZE] = {0}; + + if (code == REQUEST_OK) { + if (DeviceGetIp(ip, sizeof(ip)) < 0) { + LOG_E("get local ip failed! \n"); + return; + } + } + + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, "code", code); + json_pobject obj1, obj2; + + if (code != REQUEST_OK) { + obj1 = add_string_to_object(json, "errmsg", "connect wifi failed!"); + obj1 = add_object_to_object(json, "result"); + } else { + obj1 = add_object_to_object(json, "result"); + obj2 = add_number_to_object(obj1, "cmd", CMD_CONFIG); + obj2 = add_string_to_object(obj1, "ip", (const char *)ip); + } + + char *msg = json_to_string(json); + const char *eof = "\r\n"; + LOG_D("send msg : %s \n", msg); + if (send(sockfd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return; + } + send(sockfd, eof, strlen(eof), 0); + + delete_json_object(json); +} + +static int NetCfgConnect(const char *ssid, const char *pwd, bool wait) +{ + int timecnt = 0; + int retval = 0; + if (WifiStaStart(NetCfgConnectStatus) < 0) { + LOG_E("wifista_start \n"); + return -1; + } + + if (WifiStaConnect((const char *)ssid, (const char *)pwd) < 0) { + LOG_E("hal_wifi_start_connect \n"); + return -1; + } + + if (wait) { + while (g_netManager.status != NET_STA_CONNECTTED) { + usleep(USLEEP_500MS); + if (++timecnt > CONNECT_TIMEOUT) { + retval = -1; + break; + } + } + } + + return retval; +} + +static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl) +{ + json_handle json; + json_pobject sub; + + int cmd; + char *ps = NULL; + char *pw = NULL; + + json = parse_json(psr); + if (json == NULL) { + LOG_E("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + if (cmd != CMD_CONFIG) { + LOG_E("CMD TYPE FAILED! cmd=%d \n", cmd); + return -1; + } + + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + LOG_E("get param obj failed! \n"); + free_json(json); + return -1; + } + ps = get_json_string(sub, VAL_KEY); + if (ps == NULL) { + LOG_E("get ssid failed! \n"); + free_json(json); + return -1; + } + + if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + pw = get_json_string(sub, PWD_KEY); + if (pw != NULL) { + LOG_D("pw=%s\n", pw); + if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + } + + free_json(json); + return 0; +} + +static int NetCfgGetSocketValue(int sockfd) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + struct sockaddr_in addr; + socklen_t len; + int result = -1; + char ssid[SSID_MAX_LEN + 1] = {0}; + char pwd[PWD_MAX_LEN + 1] = {0}; + while (1) { + int readBytes; + len = sizeof(addr); + if (g_netManager.mode != NET_MODE_CONFIG) { + break; + } + if (memset_s(recvbuf, BUF_SHORT_SIZE, 0, BUF_SHORT_SIZE) < 0) { + break; + } + readBytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len); + if (readBytes <= 0) { + LOG_E("socket disconnect! \n"); + break; + } + if (ParseWifiInfo((const char*)recvbuf, ssid, sizeof(ssid), pwd, sizeof(pwd)) == 0) { + result = 0; + break; + } + } + if (result != -1) { + int code = REQUEST_OK; + SET_NET_EVENT(NET_STA_CONNECTTING, NET_EVENT_CONNECTTING, NULL); + if (NetCfgConnect(ssid, pwd, true) < 0) { + code = REQUEST_ERR; + WifiStaStop(); + result = -1; + } + + usleep(USLEEP_2000MS); // wait ip ready + SendLocalIp(sockfd, code); + usleep(USLEEP_1000MS); + if (result != -1) { + NetServerStart(); + usleep(USLEEP_100MS); // wait ip ready + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } else { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONN_FAILED, NULL); + } + } + + if (memset_s(pwd, sizeof(pwd), 0x00, sizeof(pwd)) < 0) { + return -1; + } + return result; +} + +static int NetCfgSocket(void) +{ + int sockfd; + struct sockaddr_in servaddr; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + LOG_E("socket error! \n"); + return -1; + } + + memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(NET_PORT); + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + LOG_D("监听%d端口\n", NET_PORT); + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { + LOG_E("bind socket! \n"); + close(sockfd); + return -1; + } + + if (listen(sockfd, 1) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + close(sockfd); + return -1; + } + + while (g_netManager.mode == NET_MODE_CONFIG) { + int newfd, retval; + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length); + LOG_D("new socket connect!\n"); + retval = NetCfgGetSocketValue(newfd); + close(newfd); + + if (retval == 0) { + LOG_D("config network success! \n"); + g_netManager.mode = NET_MODE_STA; + } + } + + close(sockfd); + + return 0; +} + +static void NetCfgStartConfig(void) +{ + SET_NET_EVENT(NET_STA_CONFIG, NET_EVENT_CONFIG, NULL); + WifiStaStop(); + if (SoftApStart(g_apName) < 0) { + LOG_E("start softap failed! \n"); + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + if (NetCfgSocket() < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + SoftApStop(); +} + +static void *NetCfgTask(void *arg) +{ + (void)arg; + int netCfgMode = NET_STA_NULL; + while (g_netManager.netRun) { + if (netCfgMode == g_netManager.mode && netCfgMode != NET_MODE_STA) { + usleep(USLEEP_1000MS); + continue; + } + if (netCfgMode != g_netManager.mode) { + netCfgMode = g_netManager.mode; + } + switch (netCfgMode) { + case NET_MODE_CONFIG: + NetCfgStartConfig(); + break; + default: + break; + } + usleep(USLEEP_1000MS); + } + + return NULL; +} + +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + + if (memset_s(&g_netManager, sizeof(g_netManager), 0x00, sizeof(g_netManager)) < 0) { + LOG_E("memset_s g_netManager \n"); + return -1; + } + + g_netManager.gEventCall = nEventCallback; + g_netManager.netRun = true; + g_netManager.mode = NET_STA_CONFIG; + g_apName = apName; + attr.name = "NetManagerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NET_TASK_STACK_SIZE; + attr.priority = NET_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)NetCfgTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetManagerTask!\n"); + return -1; + } + + return 0; +} + +void NetCfgStop(void) +{ + g_netManager.netRun = false; +} + +void NetCfgSetMode(int mode) +{ + g_netManager.mode = mode; +} + +void NetCfgStartConnect(const char *ssid, const char *pwd) +{ + NetCfgConnect(ssid, pwd, false); +} diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_manager_service.c b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_manager_service.c new file mode 100755 index 0000000000000000000000000000000000000000..98418e2d5058fc7476097fb327531973165da267 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_manager_service.c @@ -0,0 +1,64 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "network_server.h" +#include "network_config.h" +#include "defines.h" + +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback) +{ + if (NetServerInit(nEventCallback) < 0) { + LOG_E("NetServerInit \n"); + return -1; + } + + if (NetCfgStart(apName, nEventCallback) < 0) { + LOG_E("NetCfgStart \n"); + NetServerDeinit(); + return -1; + } + + return 0; +} + +void NetManagerUnRegister(void) +{ + NetServerDeinit(); + NetCfgStop(); +} + +void NetManagerSetNetMode(int mode) +{ + NetCfgSetMode(mode); +} + +int NetManagerSendMsg(const char *msg) +{ + return NetServerSendMsg(msg); +} diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_server.c b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_server.c new file mode 100755 index 0000000000000000000000000000000000000000..4b89a558493555e8215b9d74871585bfd078bb9f --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/src/network_server.c @@ -0,0 +1,327 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "common_log.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "json/jsonutil.h" +#include "network_server.h" +#include "defines.h" + +#define SERVER_PORT 8787 +#define MAX_CONNECT 10 + +typedef struct { + int sockfd[MAX_CONNECT]; + int connAmount; + bool isActive; + bool serRun; + + NetManagerEventCallback g_call; +}NetServerInfo; + +static NetServerInfo g_netServer; + +static int NetServerSend(int fd, const char *msg) +{ + const char *eof = "\r\n"; + if (send(fd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return -1; + } + LOG_D("send msg : %s \n", msg); + send(fd, eof, strlen(eof), 0); + + return 0; +} + +static void SendRequest(int sockfd, int code) +{ + json_pobject obj; + json_pobject json = create_json_object(); + + obj = add_number_to_object(json, "code", code); + if (code == REQUEST_OK) { + obj = add_string_to_object(json, "errmsg", ""); + } else { + obj = add_string_to_object(json, "errmsg", "explain params error!"); + } + + char *msg = json_to_string(json); + NetServerSend(sockfd, msg); + delete_json_object(json); +} + +static bool IsSpecialSocket(const char *msg) +{ + char buf[] = {0xff, 0x55, 0xaa, 0x55, 0x00}; + bool result = true; + if (msg == NULL || strlen(msg) < strlen(buf)) { + return false; + } + + for (int i = 0; i < strlen(buf); i++) { + if (msg[i] != buf[i]) { + result = false; + break; + } + } + + return result; +} + +static int ReadHandle(int *sockfd, fd_set *fdSet) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + int recvbytes; + int fd = *sockfd; + int errcode = -1; + + recvbytes = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0); + if (recvbytes <= 0) { + LOG_E("recv failed! socket may quit!\n"); + FD_CLR(fd, fdSet); + close(fd); + *sockfd = -1; + g_netServer.connAmount--; + return -1; + } + + if (g_netServer.sockfd[0] == -1 && IsSpecialSocket(recvbuf)) { + *sockfd = -1; + g_netServer.sockfd[0] = fd; + return 0; + } + + LOG_D("recv msg[%d] : %s \n", recvbytes, recvbuf); + if (g_netServer.g_call) { + errcode = g_netServer.g_call(NET_EVENT_RECV_DATA, recvbuf); + } + + if (errcode == -1) { + errcode = REQUEST_ERR; + } else { + errcode = REQUEST_OK; + } + + SendRequest(fd, errcode); + + return 0; +} + +static void CheckNewSocket(int sockFd, fd_set *fdSet, int *maxFd) +{ + int newfd; + struct sockaddr_in client_addr; + socklen_t sin_size = sizeof(client_addr); + if (FD_ISSET(sockFd, fdSet) == 0) { + return; + } + + newfd = accept(sockFd, (struct sockaddr *)&client_addr, &sin_size); + LOG_D("accept:: sock_fd = %d, newfd = %d\n", sockFd, newfd); + if (newfd < 0) { + LOG_E("accept:\n"); + return; + } + + g_netServer.connAmount++; + + if (g_netServer.connAmount < MAX_CONNECT) { + for (int i = 1; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] == -1) { + g_netServer.sockfd[i] = newfd; + break; + } + } + + if (newfd > *maxFd) { + *maxFd = newfd; + } + } else { + LOG_E("max connections arrive, exit\n"); + close(newfd); + } +} + +static void SocketListen(int sock_fd) +{ + fd_set fdset; + int maxsock; + maxsock = sock_fd; + + while (g_netServer.serRun) { + int ret; + struct timeval tv = {2, 0}; + FD_ZERO(&fdset); + FD_SET(sock_fd, &fdset); + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + FD_SET(g_netServer.sockfd[i], &fdset); + } + } + ret = select(maxsock + 1, &fdset, NULL, NULL, &tv); + if (ret <= 0) { + continue; + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1 && FD_ISSET(g_netServer.sockfd[i], &fdset)) { + LOG_D("g_netServer.sockfd[%d] = %d\n", i, g_netServer.sockfd[i]); + ReadHandle(&g_netServer.sockfd[i], &fdset); + continue; + } + } + + CheckNewSocket(sock_fd, &fdset, &maxsock); + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + close(g_netServer.sockfd[i]); + g_netServer.sockfd[i] = -1; + } + } +} + +static void StartServer(void) +{ + struct sockaddr_in serv_addr; + int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) { + LOG_E("socket failed! \n"); + g_netServer.serRun = false; + return; + } + + if (memset_s(&serv_addr, sizeof(serv_addr), 0, sizeof(serv_addr)) < 0) { + LOG_E("memset_s faield! \n"); + close(sockfd); + g_netServer.serRun = false; + return; + } + + serv_addr.sin_family = AF_INET; // 使用IPv4地址 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(SERVER_PORT); // 端口 + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + LOG_E("bind failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + if (listen(sockfd, MAX_CONNECT) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + SocketListen(sockfd); + + LOG_D("SOCKET SERVER QUIT! \n"); + + close(sockfd); +} + +static void *NetServerTask(void *param) +{ + while (g_netServer.isActive) { + if (g_netServer.serRun == false) { + usleep(USLEEP_100MS); + continue; + } + + StartServer(); + } + + return NULL; +} + +int NetServerInit(NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + attr.name = "NetServerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NETSERVER_TASK_STACK_SIZE; + attr.priority = NETSERVER_TASK_PRIO; + + if (memset_s(&g_netServer, sizeof(g_netServer), 0x00, sizeof(g_netServer)) < 0) { + LOG_E("memset_s failed! \n"); + return -1; + } + for (int i = 0; i < MAX_CONNECT; i++) { + g_netServer.sockfd[i] = -1; + } + g_netServer.isActive = true; + g_netServer.g_call = nEventCallback; + if (osThreadNew((osThreadFunc_t)NetServerTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetServerTask!\n"); + g_netServer.isActive = false; + return -1; + } + + return 0; +} + +void NetServerDeinit(void) +{ + g_netServer.serRun = false; + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + shutdown(g_netServer.sockfd[i], SHUT_RDWR); + g_netServer.sockfd[i] = -1; + } + } + + osDelay(DELAY_200MS); + g_netServer.isActive = false; +} + +void NetServerStart(void) +{ + g_netServer.serRun = true; +} + +void NetServerStop(void) +{ + g_netServer.serRun = false; + osDelay(DELAY_200MS); +} + +bool NetServerIsRun(void) +{ + return g_netServer.serRun; +} + +int NetServerSendMsg(const char *msg) +{ + if (g_netServer.serRun == false || g_netServer.sockfd[0] == -1) { + LOG_E("net server is not run! \n"); + return -1; + } + + return NetServerSend(g_netServer.sockfd[0], msg); +} diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/src/softap.c b/ScenarioDemos/SmartFanDevice/common/netcfg/src/softap.c new file mode 100755 index 0000000000000000000000000000000000000000..c57f015910ace7c263d13d4f8421e88270420f95 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/src/softap.c @@ -0,0 +1,82 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "softap.h" +#include "defines.h" + +static void ResetAddr(struct netif *pst_lwip_netif) +{ + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + + IP4_ADDR(&st_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&st_gw, 0, 0, 0, 0); + IP4_ADDR(&st_netmask, 0, 0, 0, 0); + + netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw); +} + +int SoftApStart(const char *ap_name) +{ + HotspotConfig config = {0}; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + char *apName = ap_name; + char ifname[BUF_SHORT_SIZE] = {0}; + int retval; + + if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_ACTIVE \n"); + return -1; + } + if (apName == NULL) { + apName = AP_NAME; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), apName) != 0) { + printf("[sample] strcpy ssid fail.\n"); + return -1; + } + config.securityType = WIFI_SEC_TYPE_OPEN; + retval = SetHotspotConfig((const HotspotConfig *)(&config)); + if (retval != WIFI_SUCCESS) { + LOG_E("SetHotspotConfig \n"); + return -1; + } + + retval = EnableHotspot(); + if (retval != WIFI_SUCCESS) { + LOG_E("EnableHotspot failed! \n"); + return -1; + } + + return 0; +} + +void SoftApStop(void) +{ + if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_NOT_ACTIVE \n"); + return; + } + + DisableHotspot(); +} diff --git a/ScenarioDemos/SmartFanDevice/common/netcfg/src/wifi_sta.c b/ScenarioDemos/SmartFanDevice/common/netcfg/src/wifi_sta.c new file mode 100755 index 0000000000000000000000000000000000000000..c1b3ebf8ffc1f09a5446ff52867590da9aea67bb --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/common/netcfg/src/wifi_sta.c @@ -0,0 +1,128 @@ + +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_sta.h" +#include "defines.h" + +#define TEST_CONNECT_RETRY_COUNT 5 + +static WifiEvent g_staEventHandler = {0}; +static WifiChangeEvent g_wifiChange = NULL; +static int g_connectRetryCount = 0; + +static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (state == WIFI_STATE_AVALIABLE) { + LOG_I("WiFi: Connected.\n"); + g_connectRetryCount = 0; + } else if (state == WIFI_STATE_NOT_AVALIABLE) { + LOG_I("WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason); + if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) { + g_connectRetryCount++; + return; + } + } + if (g_wifiChange) { + g_wifiChange(state); + } +} + +int WifiStaStart(WifiChangeEvent WifiChange) +{ + WifiErrorCode error; + + g_wifiChange = WifiChange; + + if (IsWifiActive() == WIFI_STA_ACTIVE) { + LOG_E("the wifi has been enabled! \n"); + return 1; + } + + error = EnableWifi(); + if (error != WIFI_SUCCESS) { + LOG_E("EnableWifi failed! \n"); + return -1; + } + + g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler; + error = RegisterWifiEvent(&g_staEventHandler); + if (error != WIFI_SUCCESS) { + LOG_E("RegisterWifiEvent fail, error = %d\n", error); + return -1; + } + + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return -1; + } + + return 0; +} + +int WifiStaConnect(const char *ssid, const char *pwd) +{ + WifiDeviceConfig config = {0}; + int netId = 0; + WifiErrorCode error; + + if (ssid == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), ssid) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + + config.ipType = DHCP; + if (pwd == NULL || strlen(pwd) == 0) { + config.securityType = WIFI_SEC_TYPE_OPEN; + } else { + config.securityType = WIFI_SEC_TYPE_PSK; + if (strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), pwd) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + } + + error = AddDeviceConfig(&config, &netId); + if (error != WIFI_SUCCESS) { + LOG_E("AddDeviceConfig! \n"); + return -1; + } + + error = ConnectTo(netId); + if (error != WIFI_SUCCESS) { + LOG_E("ConnectTo! \n"); + return -1; + } + + return 0; +} + +void WifiStaStop(void) +{ + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return; + } + + DisableWifi(); + UnRegisterWifiEvent(&g_staEventHandler); +} + diff --git a/ScenarioDemos/SmartFanDevice/screenshoot/device/fan_control.png b/ScenarioDemos/SmartFanDevice/screenshoot/device/fan_control.png new file mode 100755 index 0000000000000000000000000000000000000000..d39c61cf6cd81509a1b65331496473b5e4493255 Binary files /dev/null and b/ScenarioDemos/SmartFanDevice/screenshoot/device/fan_control.png differ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/BUILD.gn b/ScenarioDemos/SmartFanDevice/smartfan/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..9332ca5666d6a072dd3c2559ea4370076854b9e6 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("smartfan") { + sources = [ + "src/sensor.c", + "src/oled.c", + "src/pwm.c", + "src/keypad.c", + "src/common.c", + "src/fan.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/code_tab.h b/ScenarioDemos/SmartFanDevice/smartfan/include/code_tab.h new file mode 100755 index 0000000000000000000000000000000000000000..147f769121c49758d8fea0149d1dea1551483404 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/code_tab.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CODE_TAB_H__ +#define _CODE_TAB_H__ + +/* **************************16*16******** */ +const unsigned char F16X16[] = { + 0x10, 0x60, 0x02, 0x8C, 0x00, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x40, 0x7E, 0x42, 0x42, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x00, /* "温", 0 */ + 0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x44, 0x48, 0x50, 0x7F, 0x40, 0x40, 0x7F, 0x50, 0x48, 0x44, 0x40, 0x00, /* "湿", 1 */ + 0x00, 0x00, 0xFC, 0x24, 0x24, 0x24, 0xFC, 0x25, 0x26, 0x24, 0xFC, 0x24, 0x24, 0x24, 0x04, 0x00, + 0x40, 0x30, 0x8F, 0x80, 0x84, 0x4C, 0x55, 0x25, 0x25, 0x25, 0x55, 0x4C, 0x80, 0x80, 0x80, 0x00, /* "度", 2 */ +}; + +const unsigned char HZ_F16X16[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0x80, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x80, 0x00}, + {0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* "开", 1 */ + { + {0x00, 0x20, 0x20, 0x20, 0xA0, 0x60, 0x00, 0xFF, 0x60, 0x80, 0x40, 0x20, 0x18, 0x00, 0x00, 0x00}, + {0x20, 0x10, 0x08, 0x06, 0x01, 0x40, 0x80, 0x7F, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00} + }, /* "水", 2 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 3 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 4 */ + { + {0x00, 0x02, 0x0C, 0xC0, 0x00, 0xF0, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00}, + {0x02, 0x02, 0x7F, 0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x0F, 0x00, 0x00} + }, /* "冲", 5 */ + { + {0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x04, 0x04, 0xFC, 0x04, 0xC4, 0xB4, 0x8C, 0x80, 0x00, 0x00}, + {0x40, 0x22, 0x15, 0x08, 0x16, 0xA1, 0x60, 0x1C, 0x03, 0x00, 0x40, 0x80, 0x40, 0x3F, 0x00, 0x00} + }, /* "奶", 6 */ + { + {0x00, 0x04, 0x04, 0xF4, 0x94, 0x94, 0x94, 0x9F, 0x94, 0x94, 0x94, 0xF4, 0x04, 0x04, 0x00, 0x00}, + {0x40, 0x40, 0x40, 0x7F, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x7F, 0x40, 0x40, 0x40, 0x00} + }, /* "直", 7 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 8 */ +}; + +const unsigned char HZ_F16X16_1[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x10, 0xFF, 0x10, 0x10, 0xF0, 0x00, 0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00}, + {0x0F, 0x04, 0x84, 0x4F, 0x30, 0x0F, 0x40, 0x80, 0x7F, 0x00, 0x7F, 0x20, 0x20, 0x7F, 0x00, 0x00} + }, /* "咖", 1 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x00, 0x08, 0x88, 0x88, 0xFF, 0x00, 0x00, 0xFF, 0x88, 0x88, 0x08, 0x00}, + {0x0F, 0x04, 0x04, 0x0F, 0x00, 0x08, 0x08, 0x08, 0xFF, 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, 0x00} + }, /* "啡", 2 */ + { + {0x04, 0x04, 0x04, 0x84, 0x6F, 0x04, 0x04, 0x04, 0xE4, 0x04, 0x8F, 0x44, 0x24, 0x04, 0x04, 0x00}, + {0x04, 0x02, 0x01, 0xFF, 0x00, 0x10, 0x08, 0x04, 0x3F, 0x41, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00} + }, /* "花", 3 */ + { + {0x40, 0x44, 0x54, 0x54, 0x55, 0x56, 0xD4, 0x7C, 0x54, 0x56, 0x55, 0x54, 0x54, 0x44, 0x40, 0x00}, + {0x02, 0x82, 0x82, 0x9A, 0x56, 0x53, 0x22, 0x22, 0x22, 0x52, 0x4E, 0x42, 0x82, 0x02, 0x02, 0x00} + }, /* "姜", 4 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 5 */ +}; + +/* ***********************************6*8*********************************** */ +const unsigned char F6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // ,1 + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ; + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/* ***************************************8*16*********************************** */ +const unsigned char F8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // !1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // #3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // %5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // &6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // (8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // )9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // *10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // +11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // ,12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // -13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // .14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ; 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +const unsigned char BMP1[] = { + 0x00, 0x03, 0x05, 0x09, 0x11, 0xFF, 0x11, 0x89, 0x05, 0xC3, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0xFF, 0x11, 0xAA, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x38, 0x44, 0x82, 0x92, + 0x92, 0x74, 0x01, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x44, 0xC7, 0x01, 0x7D, + 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, + 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, + 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0x00, 0x00, 0xD8, 0xD8, 0xD8, 0xD8, + 0xD8, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0xE6, 0x66, 0x20, 0x00, 0x06, 0x06, 0x86, 0x06, + 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x86, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, + 0x00, 0x86, 0x86, 0x86, 0x86, 0x86, 0x80, 0x80, 0x86, 0x86, 0x06, 0x86, 0x86, 0xC0, 0xC0, 0x86, + 0x86, 0x86, 0x06, 0x06, 0xD0, 0x30, 0x76, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0xFE, 0x00, 0x01, + 0x02, 0x00, 0xC4, 0x18, 0x20, 0x02, 0x9E, 0x63, 0xB2, 0x0E, 0x00, 0xFF, 0x81, 0x81, 0xFF, 0x00, + 0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x23, 0xEA, 0xAA, 0xBF, 0xAA, + 0xEA, 0x03, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x01, 0x09, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xC1, 0xFF, + 0xFF, 0xC1, 0xC1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0xFC, 0xF3, 0xEF, 0xF3, 0xFC, + 0x80, 0xFF, 0x80, 0xEE, 0xEE, 0xEE, 0xF5, 0xFB, 0xFF, 0x9C, 0xBE, 0xB6, 0xB6, 0x88, 0xFF, 0x00, + /* MP3_UI.bmp */ +}; +#endif // _CODE_TAB_H__ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/common.h b/ScenarioDemos/SmartFanDevice/smartfan/include/common.h new file mode 100755 index 0000000000000000000000000000000000000000..031e9b1c803218eb065dcf934a551e0a75ab3e71 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/common.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WINDER_COMMON_H__ +#define __WINDER_COMMON_H__ + + +/** + * @brief Init the common device + * + * @since 1.0 + * @version 1.0 + * + */ +void DeviceInit(void); + +#endif /* __WINDER_COMMON_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/defines.h b/ScenarioDemos/SmartFanDevice/smartfan/include/defines.h new file mode 100755 index 0000000000000000000000000000000000000000..8a6bf45e619a64d2841b1acdbb034d5d63f3330c --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/defines.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define FANDBG(fmt, args...) printf("[FAN_DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define FANERR(fmt, args...) printf("[FAN_ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) +#define FANPRN(fmt, args...) printf("[FAN_INFO ][%s|%d]" fmt, __func__, __LINE__, ##args) + +#define KEY_ERR(fmt, args...) printf("[KEY_ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) +#define KEY_DBG(fmt, args...) printf("[KEY_DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define KEY_PRT(fmt, args...) printf("[KEY_INFO ][%s|%d]" fmt, __func__, __LINE__, ##args) + +#define NET_ERR(fmt, args...) printf("[NETCFG_ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) +#define NET_DBG(fmt, args...) printf("[NETCFG_DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define NET_PRT(fmt, args...) printf("[NETCFG_INFO ][%s|%d]" fmt, __func__, __LINE__, ##args) + +#define OLED_ERR(fmt, arg...) printf("[OLED_ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define OLED_DBG(fmt, arg...) printf("[OLED_DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define OLED_PRT(fmt, arg...) printf("[OLED_INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define PWM_ERR(fmt, arg...) printf("[PWM_ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define PWM_DBG(fmt, arg...) printf("[PWM_DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define PWM_PRT(fmt, arg...) printf("[PWM_INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#define HOT_AP_NAME "SmartFan_AP" + +#endif /* __DEFINES_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/fan.h b/ScenarioDemos/SmartFanDevice/smartfan/include/fan.h new file mode 100755 index 0000000000000000000000000000000000000000..d8b8fe0c54484007c406e9def62f158c9f151a00 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/fan.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FAN_H__ +#define __FAN_H__ + +#include + +#define FAN_TASK_STACK_SIZE (1024*4) +#define FAN_TASK_PRIO (25) + +#define FANUPD_TASK_STACK_SIZE (1024) +#define FANUPD_TASK_PRIO (33) + +#define FAN_LOOP_DELAY (500) +#define TIMER_HALF_HOUR 30 +#define TIMER_ONE_HOUR 60 +#define TIMER_MAX_HOURS 8 +#define TIMER_60_SECOND 60 + +#define FAN_MAX_SCOP 4 + + +#define ASCII_0 ('0') +#define ASCII_1 ('1') + +#define TICKS_NUMBER (100) // 1 ticks = 10ms +#define SPEED_INCREASE 0 +#define SPEED_REDUCTION 1 + +#define BUF_SIZE 128 + +#define POWER_XPOS 0 +#define POWER_YPOS 0 +#define NETSTA_XPOS 0 +#define NETSTA_YPOS 1 +#define MODE_XPOS 0 +#define MODE_YPOS 2 +#define SPEED_XPOS 0 +#define SPEED_YPOS 3 +#define SCOPE_XPOS 0 +#define SCOPE_YPOS 4 +#define TIMER_XPOS 0 +#define TIMER_YPOS 5 +#define TEMP_XPOS 0 +#define TEMP_YPOS 6 + +#define MESSAGE_LEN 256 // 6 +#define FAN_MAX_TEMP 4 +#define FAN_SCOPE_MAX 3 + +typedef enum { + MESSAGE_POWER_OFF = 1, + MESSAGE_SPEED_SET, + MESSAGE_SPEED_MODE, + MESSAGE_SCOP_SET, + MESSAGE_TIMER_ONOFF, + MESSAGE_TEMP_SET, + MESSAGE_TIMER_SET +}MESSAGE_TYPE; + +typedef enum { + FAN_MODE_SLEEP = 1, + FAN_MODE_NATURAL, + FAN_MODE_AUTO, + + FAN_MODE_NBR +}FAN_MODE; + +#endif /* __FAN_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/keypad.h b/ScenarioDemos/SmartFanDevice/smartfan/include/keypad.h new file mode 100755 index 0000000000000000000000000000000000000000..36ecd5b98d139bbb091f17a15a6f459992aa0374 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/keypad.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __KEY_PAD_H__ +#define __KEY_PAD_H__ + +#define KEY_TASK_STACK_SIZE (1024*4) +#define KEY_TASK_PRIO (30) +#define KEY_DELAY_TIME (10) + +typedef enum { + KEY_CODE_0, // menu 确认键 + KEY_CODE_1, // speed++ 速度加 + KEY_CODE_2, // speed-- 速度减 + KEY_CODE_3, // mode 风速的模式(普通模式,睡眠模式) + KEY_CODE_4, // scope 转的角度 + + KEY_CODE_N +}KEY_CODE; + +#define KEY_DOWN 1 +#define KEY_UP 0 + +#define KEY_PAD_MENU KEY_CODE_3 +#define KEY_PAD_UP KEY_CODE_1 +#define KEY_PAD_DOWN KEY_CODE_2 +#define KEY_PAD_MODE KEY_CODE_0 +#define KEY_PAD_SCOP KEY_CODE_4 + +#define KEY_PAD_NONE 0xFF + +typedef struct { + KEY_CODE code; + int value; +}KeyEvent; + +/** + * @brief key event callback + * + * @param event -- key event. reference {@KeyEvent} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +typedef int (*keypad_event_call)(KeyEvent *event); + +/** + * @brief register the key event + * + * @param gcall -- key event callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int KeyRegisterInit(keypad_event_call gcall); + +#endif /* __KEY_PAD_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/oled.h b/ScenarioDemos/SmartFanDevice/smartfan/include/oled.h new file mode 100755 index 0000000000000000000000000000000000000000..d1a9711f6e62754a8465b4f540246197fae0ae62 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/oled.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __OLED_H__ +#define __OLED_H__ + +#include "ohos_types.h" + +#define WIFI_IOT_OLED_I2C_IDX_0 0 +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 + +#define I2C_REG_ARRAY_LEN (64) +#define BH_SEND_BUFF (1) +#define OLED_SEND_BUFF_LEN (28) +#define OLED_SEND_BUFF_LEN2 (25) +#define OLED_SEND_BUFF_LEN3 (27) +#define OLED_SEND_BUFF_LEN4 (29) +#define Max_Column (128) +#define OLED_DEMO_TASK_STAK_SIZE (4096) +#define OLED_DEMO_TASK_PRIORITY (25) + +#define OLED_ADDRESS 0x78 +#define OLED_ADDRESS_WRITE_CMD 0x00 +#define OLED_ADDRESS_WRITE_DATA 0x40 + +#define OLED_CLEAN_SCREEN ((uint8)0x00) + +#define SLEEP_20_MS 20000 +#define SLEEP_100_MS 100000 + +#define DELAY_10_MS 1 +#define DELAY_100_MS 10 +#define DELAY_200_MS 20 +#define DELAY_250_MS 25 +#define DELAY_500_MS 50 +/* ssd1306 register cmd */ +#define DISPLAY_OFF 0xAE +#define SET_LOW_COLUMN_ADDRESS 0x00 +#define SET_HIGH_COLUMN_ADDRESS 0x10 +#define SET_START_LINE_ADDRESS 0x40 +#define SET_PAGE_ADDRESS 0xB0 +#define CONTRACT_CONTROL 0x81 +#define FULL_SCREEN 0xFF +#define SET_SEGMENT_REMAP 0xA1 +#define NORMAL 0xA6 +#define SET_MULTIPLEX 0xA8 +#define DUTY 0x3F +#define SCAN_DIRECTION 0xC8 +#define DISPLAY_OFFSET 0xD3 +#define DISPLAY_TYPE 0x00 +#define OSC_DIVISION 0xD5 +#define DIVISION 0x80 +#define COLOR_MODE_OFF 0xD8 +#define COLOR 0x05 +#define PRE_CHARGE_PERIOD 0xD9 +#define PERIOD 0xF1 +#define PIN_CONFIGUARTION 0xDA +#define CONFIGUARTION 0x12 +#define SET_VCOMH 0xDB +#define VCOMH 0x30 +#define SET_CHARGE_PUMP_ENABLE 0x8D +#define PUMP_ENABLE 0x14 +#define TURN_ON_OLED_PANEL 0xAF +#define CMD_LENGTH 27 + +#define OLED_I2C_WRITE_CMD_SEND_LEN 2 + +#define HORIZONTAL_COORDINATE_OF_SLOGANS 2 +#define VERTICAL_COORDINATE_OF_SLOGANS 3 +#define CHAR_SIZE_OF_LANTTICE_8_16 16 +#define HORI_PIXEL_OF_LANTTICE_8_16 8 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16 32 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16 16 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16_1 48 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16_1 16 +#define HORI_PIXEL_OF_LANTTICE_6_8 6 + +#define LIMIT_HORI_PIXEL 120 +#define MAX_LINE_OF_LANTTICE 8 +#define SET_POSITION_OFFSET 4 +#define MAX_OLED_INIT_CYCLE_TIMES 5 + + +/** + * @brief Oled Init Operations + * + * @since 1.0 + * @version 1.0 + */ +int OledInit(void); + +/** + * @brief Oled set oled ON or OFF + * @param value 0 set oled OFF, others set the oled ON + * + * @since 1.0 + * @version 1.0 + */ +void OledSetOnOff(int value); + +/** + * @brief Oled clear + * + * @since 1.0 + * @version 1.0 + */ +void OledClear(void); + + +/** + * @brief Oled Show str + * + * @param + * str The str that you want show + * length The length of the str that you want show + * x The offset of X axis + * y The offset of Y axis + * charSize The CharSize (eg: 8*6) + * @since 1.0 + * @version 1.0 + */ +void OledShowStr(const char *str, int length, uint8 x, uint8 y, uint8 charSize); + +#endif /* __OLED_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/pwm.h b/ScenarioDemos/SmartFanDevice/smartfan/include/pwm.h new file mode 100755 index 0000000000000000000000000000000000000000..21e78bb4b2bca0db13e628886f9296e30b0ede8f --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/pwm.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PWM_H__ +#define __PWM_H__ + +#include "ohos_types.h" + +#define WIFI_IOT_GPIO_IDX_2 2 +#define IOT_IO_FUNC_GPIO 0 +#define GPIO_PIN_HIGH 1 +#define GPIO_PIN_LOW 0 +#define PWM_DELAY_TIME 100 + +#define PWM_TASK_PRIO 30 +#define PWM_TASK_STACK_SIZE 512 + +typedef enum { + PWM_LEVEL_0 = 0, // 0为关闭PWM,其他对应PWM等级 + PWM_LEVEL_1, + PWM_LEVEL_2, + PWM_LEVEL_3, + PWM_LEVEL_4, + + PWM_LEVEL_NBR +} PWM_LEVEL; + +/** + * @brief pwm init + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int PwmInit(void); + +/** + * @brief set pwm level + * @param level -- pwm level, reference {@PWM_LEVEL} + * + * @since 1.0 + * @version 1.0 + * + */ +void PwmSetLevel(PWM_LEVEL level); + +/** + * @brief get pwm level + * + * @since 1.0 + * @version 1.0 + * + * @return the current pwm level + */ +int PwmGetLevel(void); + +#endif /* __PWM_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/include/sensor.h b/ScenarioDemos/SmartFanDevice/smartfan/include/sensor.h new file mode 100755 index 0000000000000000000000000000000000000000..b32da95ce2d4a51e1b0d9d4aff7bcd398da62f3f --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/include/sensor.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SENSOR_H__ +#define __SENSOR_H__ + +#define WIFI_IOT_SENSOR_I2C_IDX_0 (0) +#define AHT_SLEEP_20MS (20000) // 20ms +#define AHT_SLEEP_50MS (50000) // 50ms +#define AHT_SLEEP_1S (1000000) // 1s + +#define AHT_DELAY_10MS (1) // 10ms +#define AHT_DELAY_40MS (4) // 40ms +#define AHT_DELAY_100MS (10) // 100ms +#define AHT_DEVICE_ADDR (0x38) // device addr +#define AHT_DEVICE_READ_STATUS (0x71) // befor read tem&humi data need to send cmd to comfir the +#define AHT_DEVICE_INIT_CMD (0xBE) // aht init cmd +#define AHT_DEVICE_TEST_CMD (0xAC) // test cmd +#define AHT_DEVICE_PARAM_HIGH_BYTE (0x33) +#define AHT_DEVICE_PARAM_LOW_BYTE (0x00) +#define AHT_DEVICE_PARAM_INIT_HIGH (0x08) +#define AHT_DEVICE_CALIBRATION (0x80) +#define AHT_DEVICE_CALIBRATION_ERR (0x1C) +#define AHT_DEVICE_CALIBRATION_ERR_R (0x18) +#define AHT_TASK_SLEEP_TIME (20000) // thread sleep 20ms + +#define AHT_REG_ARRAY_LEN (6) +#define AHT_REG_TEMP_BITS_1 (3) +#define AHT_REG_TEMP_BITS_2 (4) +#define AHT_REG_TEMP_BITS_3 (5) +#define AHT_REG_TEMP_OFFSET (16) +#define AHT_REG_TEMP_OFFSET_1 (8) +#define AHT_OC_ARRAY_LEN (6) +#define AHT_SNED_CMD_LEN (3) +#define SENSOR_TASK_STAK_SIZE (1024*4) +#define SENSOR_TASK_PRIORITY (14) +#define AHT_REG_ARRAY_INIT_LEN (1) +#define AHT_CALCULATION (1048576) +#define DECIMAL 10 +#define NUMBER_OF_DECIMAL_POINTS 3 + +typedef enum { + AHT_TEMPERATURE = 1, // TEMP + AHT_HUMIDITY = 2, // HUMI +} aht_serson_type; + + +/** + * @brief The sensor init operation + * + * @return If success return WIFI_IOT_SUCCESS. else return WIFI_IOT_FAILURE. + * @since 1.0 + * @version 1.0 + */ +int SensorInit(void); + + +/** + * @brief Get the temp value of sensor. + * + * @return Return the temp value. + * @since 1.0 + * @version 1.0 + */ +int SensorGetValue(void); + +#endif /* __SENSOR_H__ */ diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/common.c b/ScenarioDemos/SmartFanDevice/smartfan/src/common.c new file mode 100755 index 0000000000000000000000000000000000000000..8d124208ed8f7068de60035f53f0c6add3974dca --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/common.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "lwip/if_api.h" +#include "lwip/netifapi.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "peripheral_hal.h" +#include "netinet/in.h" +#include "sys/ioctl.h" + +#include "common.h" +#include "defines.h" + +#define I2C_IDX_BAUDRATE (400000) + +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 +#define WIFI_IOT_I2C_IDX_0 0 + +static void I2cBusInit(void) +{ + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_13); + // Set up the gpio funcion as i2c bus 0 + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); + + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_14); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); + IoTI2cInit(WIFI_IOT_I2C_IDX_0, I2C_IDX_BAUDRATE); // Rate: 400kbps +} + +void DeviceInit(void) +{ + // disable the watchdog + HalSetWatchDogEnable(0); + I2cBusInit(); +} diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/fan.c b/ScenarioDemos/SmartFanDevice/smartfan/src/fan.c new file mode 100755 index 0000000000000000000000000000000000000000..9ba96a2b2ef521930747eb4781345d5c5d183202 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/fan.c @@ -0,0 +1,711 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include + +#include "json/jsonutil.h" +#include "ohos_init.h" +#include "securec.h" +#include "ohos_types.h" +#include "cmsis_os2.h" +#include "common.h" +#include "keypad.h" +#include "oled.h" +#include "pwm.h" +#include "sensor.h" +#include "defines.h" +#include "fan.h" + +#include "network_manager_service.h" + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "value" +#define TYP_KEY "type" +#define TIM_KEY "time" +#define DUR_KEY "total" +#define ID__KEY "id" +#define TEMP_MIN "tempMin" +#define TEMP_MAX "tempMax" +#define SPEED_KEY "speed" +#define SHARK_KEY "shark" + +#define FAN_TEMP_NBR 2 + +typedef struct { + uint8 value[FAN_TEMP_NBR]; + uint8 speed; + uint8 scope; + + bool enable; +}TempInfo; + + +typedef struct { + uint8 id; + uint32 times; + uint32 duration; + + bool enable; + uint8 speed; + uint8 scope; + uint8 flag; +}TimerInfo; + +typedef struct { + uint8 power_off; + uint8 speed_level; + uint8 speed_mode; + uint8 shake_scope; + + bool timer_flag; + uint32 timer_count; + + TimerInfo gTimer; + + TempInfo temp_info[FAN_MAX_TEMP]; + + osTimerId_t timerID; +}FanInfo; + +static FanInfo g_fan; +static bool g_netstatus = false; +static const char *g_mode_str[] = {"sleep", "natural", "auto"}; +static const char *g_scop_str[] = {"forbid", "60", "120"}; + +static void ShowPowerStatus(void) +{ + char power_sta[BUF_SIZE] = {0}; + if (sprintf_s(power_sta, BUF_SIZE, "power %s", g_fan.power_off == 1 ? "OFF" : "ON") < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + OledShowStr(" ", strlen(" "), POWER_XPOS, POWER_YPOS, 1); + OledShowStr(power_sta, strlen(power_sta), POWER_XPOS, POWER_YPOS, 1); +} + +static void ShowNetStatus(void) +{ + char netsta_buf[BUF_SIZE] = {0}; + if (sprintf_s(netsta_buf, BUF_SIZE, "net %s", g_netstatus ? "online" : "offline") < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + OledShowStr(" ", strlen(" "), NETSTA_XPOS, NETSTA_YPOS, 1); + OledShowStr(netsta_buf, strlen(netsta_buf), NETSTA_XPOS, NETSTA_YPOS, 1); +} + +static void ShowSpeedMode(void) +{ + char mode_buf[BUF_SIZE] = {0}; + if (sprintf_s(mode_buf, BUF_SIZE, "mode %s", g_mode_str[g_fan.speed_mode - 1]) < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + OledShowStr(" ", strlen(" "), MODE_XPOS, MODE_YPOS, 1); + OledShowStr(mode_buf, strlen(mode_buf), MODE_XPOS, MODE_YPOS, 1); +} + +static void ShowSpeedLevel(int speed_level) +{ + char speed_buf[BUF_SIZE] = {0}; + if (sprintf_s(speed_buf, BUF_SIZE, "wind %d", speed_level) < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + OledShowStr(" ", strlen(" "), SPEED_XPOS, SPEED_YPOS, 1); + OledShowStr(speed_buf, strlen(speed_buf), SPEED_XPOS, SPEED_YPOS, 1); +} + +static void ShowShakeScope(int shake_scope) +{ + char scope_buf[BUF_SIZE] = {0}; + if (shake_scope < 0 || shake_scope >= FAN_SCOPE_MAX) { + FANERR("OOR!\n"); + return; + } + if (sprintf_s(scope_buf, BUF_SIZE, "shake %s", g_scop_str[shake_scope]) < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + OledShowStr(" ", strlen(" "), SCOPE_XPOS, SCOPE_YPOS, 1); + OledShowStr(scope_buf, strlen(scope_buf), SCOPE_XPOS, SCOPE_YPOS, 1); +} + +static void ShowPowerOffTimer(void) +{ + char timer_buf[BUF_SIZE] = {0}; + if (g_fan.timer_flag) { + if (g_fan.gTimer.flag == 0) { + if (sprintf_s(timer_buf, BUF_SIZE, "Timer on %d", g_fan.gTimer.times) < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + } else { + if (sprintf_s(timer_buf, BUF_SIZE, "Timer off %d", g_fan.gTimer.duration) < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + } + } else { + if (sprintf_s(timer_buf, BUF_SIZE, "Timer OFF") < 0) { + FANERR("sprintf_s failed! \n"); + return; + } + } + OledShowStr(" ", strlen(" "), TIMER_XPOS, TIMER_YPOS, 1); + OledShowStr(timer_buf, strlen(timer_buf), TIMER_XPOS, TIMER_YPOS, 1); +} + +static void ShowTemperature(int temp) +{ + char temp_buf[BUF_SIZE] = {}; + static int gTemp = -1; + if (temp == gTemp) { + return; + } + gTemp = temp; + if (gTemp > 0) { + if (sprintf_s(temp_buf, BUF_SIZE, "Temp %d", gTemp) < 0) { + FANERR("get temperature string failed! \n"); + return; + } + } else { + if (sprintf_s(temp_buf, BUF_SIZE, "Temp NONE") < 0) { + return; + } + } + OledShowStr(" ", strlen(" "), TEMP_XPOS, TEMP_YPOS, 1); + OledShowStr(temp_buf, strlen(temp_buf), TEMP_XPOS, TEMP_YPOS, 1); +} + +static void FanShowInfo(void) +{ + ShowPowerStatus(); + ShowNetStatus(); + ShowSpeedMode(); + ShowSpeedLevel(g_fan.speed_level); + ShowShakeScope(g_fan.shake_scope); + ShowPowerOffTimer(); + ShowTemperature(0); +} + +static void UpdateSpeedLevel(void) +{ + ShowSpeedLevel(g_fan.speed_level); +} + +static void UpdateSpeedMode(void) +{ + ShowSpeedMode(); +} + +static int FanDealTempSet(const json_pobject json) +{ + int value, speed, scope, t1, t2; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + + value = get_json_int(json, VAL_KEY); + t1 = get_json_int(json, TEMP_MIN); + t2 = get_json_int(json, TEMP_MAX); + speed = get_json_int(json, SPEED_KEY); + scope = get_json_int(json, SHARK_KEY); + + if (speed <= 0 || speed > PWM_LEVEL_4) { + FANERR("SPEED LEVEL OOR! \n"); + return -1; + } + + if (!g_fan.temp_info[speed - 1].enable && !value) { + return; + } + + g_fan.temp_info[speed - 1].enable = value == 1 ? true : false; + g_fan.temp_info[speed - 1].value[0] = t1; + g_fan.temp_info[speed - 1].value[1] = t2; + g_fan.temp_info[speed - 1].speed = speed; + g_fan.temp_info[speed - 1].scope = scope; + + g_fan.speed_mode = FAN_MODE_AUTO; + + UpdateSpeedMode(); + + return 0; +} + +static int FanDealTimerSet(const json_pobject json) +{ + int tm, tt, id, value, speed, scope; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + FANDBG("%s \n", json_to_string(json)); + id = get_json_int(json, ID__KEY); + value = get_json_int(json, VAL_KEY); + tm = get_json_int(json, TIM_KEY); + tt = get_json_int(json, DUR_KEY); + speed = get_json_int(json, SPEED_KEY); + scope = get_json_int(json, SHARK_KEY); + if (scope > FAN_SCOPE_MAX) { + scope = FAN_SCOPE_MAX; + } + if (g_fan.gTimer.id == 0 || g_fan.gTimer.enable == false) { + g_fan.gTimer.id = id; + g_fan.gTimer.enable = value == 1 ? true : false; + g_fan.gTimer.times = tm * TIMER_60_SECOND; + g_fan.gTimer.duration = tt * TIMER_60_SECOND; + g_fan.gTimer.speed = speed; + g_fan.gTimer.scope = scope; + if (g_fan.power_off == 0 || g_fan.gTimer.times == 0) { + g_fan.gTimer.flag = 1; + PwmSetLevel(g_fan.gTimer.speed); + ShowSpeedLevel(g_fan.gTimer.speed); + ShowShakeScope(g_fan.gTimer.scope); + } else { + g_fan.gTimer.flag = 0; + } + if (g_fan.gTimer.enable) { + g_fan.timer_flag = 1; + } else { + g_fan.timer_flag = 0; + } + ShowPowerOffTimer(); + } + + return 0; +} + +static int FanDealScope(const json_pobject json) +{ + int value; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + value = get_json_int(json, VAL_KEY); + if (g_fan.shake_scope != value && value <= FAN_SCOPE_MAX) { + g_fan.shake_scope = value; + ShowShakeScope(g_fan.shake_scope); + } + + return 0; +} + +static int FanDealMode(const json_pobject json) +{ + int value; + bool updateSpeed = false; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + value = get_json_int(json, VAL_KEY); + FANDBG("g_fan.speed_mode : %d, value : %d \n", g_fan.speed_mode, value); + if (g_fan.speed_mode != value) { + g_fan.speed_mode = value; + if (g_fan.speed_mode == FAN_MODE_SLEEP && g_fan.speed_level > PWM_LEVEL_2) { + g_fan.speed_level = PWM_LEVEL_1; + updateSpeed = true; + } else if (g_fan.speed_mode == FAN_MODE_NATURAL && g_fan.speed_level < PWM_LEVEL_3) { + g_fan.speed_level = PWM_LEVEL_3; + updateSpeed = true; + } + PwmSetLevel(g_fan.speed_level); + ShowSpeedMode(); + if (updateSpeed) { + UpdateSpeedLevel(); + } + } +} + +static int FanDealSpeed(const json_pobject json) +{ + int value; + bool updateMode = false; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + value = get_json_int(json, VAL_KEY); + FANDBG("g_fan.speed_level = %d, value=%d \n", g_fan.speed_level, value); + if (g_fan.speed_level != value) { + g_fan.speed_level = value; + PwmSetLevel(g_fan.speed_level); + if (g_fan.speed_level < PWM_LEVEL_3 && g_fan.speed_mode != FAN_MODE_SLEEP) { + g_fan.speed_mode = FAN_MODE_SLEEP; + updateMode = true; + } else if (g_fan.speed_level >= PWM_LEVEL_3 && g_fan.speed_mode != FAN_MODE_NATURAL) { + g_fan.speed_mode = FAN_MODE_NATURAL; + updateMode = true; + } + + ShowSpeedLevel(g_fan.speed_level); + if (updateMode) { + UpdateSpeedMode(); + } + } + + return 0; +} + +static int FanDealPoweroff(const json_pobject json) +{ + int value; + if (json == NULL) { + FANERR("FanDealPoweroff failed! \n"); + return -1; + } + value = get_json_int(json, VAL_KEY); + if (value == 0) { + g_fan.power_off = 1; + PwmSetLevel(PWM_LEVEL_0); + } else { + g_fan.power_off = 0; + PwmSetLevel(g_fan.speed_level); + } + ShowPowerStatus(); + + return 0; +} + +typedef struct { + int cmd; + int (*ProcessFunc)(const json_pobject json); +} MsgProcess; + +static MsgProcess g_msgProcess[] = { + {MESSAGE_POWER_OFF, FanDealPoweroff}, + {MESSAGE_SPEED_SET, FanDealSpeed}, + {MESSAGE_SPEED_MODE, FanDealMode}, + {MESSAGE_SCOP_SET, FanDealScope}, + {MESSAGE_TIMER_SET, FanDealTimerSet}, + {MESSAGE_TEMP_SET, FanDealTempSet} +}; + +static void FanProcessAppMessage(const char *data, int data_len) +{ + int cmd; + json_handle json; + json_pobject sub; + FANDBG("data : %s \n", data); + json = parse_json(data); + if (json == NULL) { + FANERR("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + FANERR("get param obj failed! \n"); + free_json(json); + return -1; + } + + FANDBG("cmd=%d \n", cmd); + for (uint8 i = 0; i < ARRAYSIZE(g_msgProcess); i++) { + if (g_msgProcess[i].cmd == cmd) { + if (g_msgProcess[i].ProcessFunc(sub) < 0) { + FANERR("do process func failed! \n"); + } + break; + } + } +} + +static int GenerateJsonData(char *buff, int length, int cmd, int value) +{ + int retval = 0; + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, CMD_KEY, cmd); + json_pobject obj1 = add_object_to_object(json, PAR_KEY); + json_pobject obj2 = add_number_to_object(obj1, VAL_KEY, value); + + char *msg = json_to_string(json); + if (strncpy_s(buff, length, msg, strlen(msg)) < 0) { + retval = -1; + } + FANDBG("retval=%d, msg:%s, buff:%s \n", retval, msg, buff); + delete_json_object(json); + + return retval; +} + +static int FanSpeedChange(int position, char *message_buf, int length) +{ + uint8 value; + if (message_buf == NULL || length < MESSAGE_LEN) { + FANERR("NULL POINT!\n"); + return -1; + } + + if (position == SPEED_INCREASE) { + if (g_fan.speed_level == PWM_LEVEL_4) + return 1; + value = g_fan.speed_level + 1; + } else { + if (g_fan.speed_level == PWM_LEVEL_1) + return 1; + value = g_fan.speed_level - 1; + } + + return GenerateJsonData(message_buf, length, MESSAGE_SPEED_SET, value); +} + +static int FanPowerOff(char *message_buf, int length) +{ + uint8 value; + if (message_buf == NULL || length < MESSAGE_LEN) { + FANERR("NULL POINT!\n"); + return -1; + } + g_fan.power_off = !g_fan.power_off; + value = g_fan.power_off; + + return GenerateJsonData(message_buf, length, MESSAGE_POWER_OFF, value); +} + +static int FanSpeedIncrease(char *buff, int length) +{ + return FanSpeedChange(SPEED_INCREASE, buff, length); +} + +static int FanSpeedReduction(char *buff, int length) +{ + return FanSpeedChange(SPEED_REDUCTION, buff, length); +} + +typedef struct { + int keycode; + int (*KeyFunc)(char *buff, int length); +}KeyProcess; + +static KeyProcess g_keyProcess[] = { + {KEY_PAD_UP, FanSpeedIncrease}, + {KEY_PAD_DOWN, FanSpeedReduction}, + {KEY_PAD_MODE, FanPowerOff} +}; + +static int FanKeyEventHandle(KeyEvent *event) +{ + char message_buf[MESSAGE_LEN + 1] = {0}; + bool message_ready = false; + + FANDBG("keycode = %d \n", event->code); + for (uint8 i = 0; i < ARRAYSIZE(g_keyProcess); i++) { + if (event->code == g_keyProcess[i].keycode) { + if (g_keyProcess[i].KeyFunc(message_buf, sizeof(message_buf)) == 0) { + message_ready = true; + break; + } + } + } + + if (message_ready) { // effective button + FanProcessAppMessage((const char *)message_buf, strlen(message_buf)); // message function + FANDBG("message_buf : %s \n\n", message_buf); + NetManagerSendMsg((char *)message_buf); // send message to FA + } + + return 0; +} + +static int FanNetEventHandler(NET_EVENT_TYPE event, const void *data) +{ + FANDBG("event = %d \n", event); + switch (event) { + case NET_EVENT_CONNECTTED: + g_netstatus = true; + ShowNetStatus(); + break; + case NET_EVENT_RECV_DATA: + FanProcessAppMessage((const char *)data, strlen(data)); + break; + default: + break; + } + return 0; +} + +typedef struct { + int w_speed; + int w_scope; +}UpdateInfo; + +static void *FanUpdateTask(void *args) +{ + UpdateInfo *info = (UpdateInfo *)args; + PwmSetLevel(info->w_speed); + ShowSpeedLevel(info->w_speed); + ShowShakeScope(info->w_scope); + // notify FA the status changed + + return NULL; +} + +static void FanUpdate(int speed, int scope) +{ + UpdateInfo info; + osThreadAttr_t attr; + attr.name = "updateTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = FANUPD_TASK_STACK_SIZE; + attr.priority = FANUPD_TASK_PRIO; + info.w_speed = speed; + info.w_scope = scope; + + if (osThreadNew((osThreadFunc_t)FanUpdateTask, &info, &attr) == NULL) { + FANERR("Falied to create FanUpdateTask!\n"); + } +} + +static void FanTimerHandler(void *arg) +{ + (void)arg; + + if (g_fan.timer_flag) { + if (g_fan.gTimer.flag == 0) { + if (--g_fan.gTimer.times <= 0) { + g_fan.gTimer.times = 0; + g_fan.gTimer.flag = 1; + g_fan.power_off = 0; + FanUpdate(g_fan.gTimer.speed, g_fan.gTimer.scope); + } + } else { + if (--g_fan.gTimer.duration <= 0) { + g_fan.timer_flag = 0; + g_fan.gTimer.duration = 0; + g_fan.gTimer.flag = 0; + g_fan.gTimer.enable = false; + FanUpdate(g_fan.speed_level, g_fan.shake_scope); + } + } + } +} + +static void FanStartTimer(void) +{ + g_fan.timerID = osTimerNew(&FanTimerHandler, osTimerPeriodic, NULL, NULL); + osTimerStart(g_fan.timerID, TICKS_NUMBER); +} + +static int FanGetTempLevel(int temp) +{ + for (int i = 0; i < FAN_MAX_TEMP; i++) { + if (g_fan.temp_info[i].enable && + temp >= g_fan.temp_info[i].value[0] && + temp < g_fan.temp_info[i].value[1]) { + g_fan.shake_scope = g_fan.temp_info[i].scope; + + return g_fan.temp_info[i].speed; + } + } + + return 0; +} + +static void FanInit(void) +{ + DeviceInit(); + PwmInit(); + SensorInit(); + + if (OledInit() != 0) { + FANERR("OledInit failed! \n"); + while (1) { + } + } +} + +static void FanLoop(void) +{ + while (1) { + if (g_fan.power_off) { + if (PwmGetLevel() != PWM_LEVEL_0) { + PwmSetLevel(PWM_LEVEL_0); + ShowSpeedLevel(g_fan.speed_level); // display the speedlevel + ShowPowerStatus(); + } + osDelay(FAN_LOOP_DELAY); + continue; + } + if (g_fan.speed_mode == FAN_MODE_AUTO) { + int speed; + int temp = SensorGetValue(); + speed = FanGetTempLevel(temp); + if (speed != 0 && speed != g_fan.speed_level) { + FANDBG("speed = %d \n", speed); + g_fan.speed_level = speed; + PwmSetLevel(g_fan.speed_level); + ShowSpeedLevel(g_fan.speed_level); + ShowShakeScope(g_fan.shake_scope); + // notify FA the status changed + } + ShowTemperature(temp); + } + osDelay(FAN_LOOP_DELAY); + } +} + +static void *FanTask(const char *arg) +{ + (void)arg; + FANDBG("FanTask Enter! \n"); + FanInit(); + (void)memset_s(&g_fan, sizeof(g_fan), 0x00, sizeof(g_fan)); + g_fan.speed_mode = FAN_MODE_SLEEP; + g_fan.speed_level = PWM_LEVEL_1; + + if (KeyRegisterInit(FanKeyEventHandle) != 0) { // register button callback + FANERR("KeyRegisterInit failed!!! \n"); + } + + FanStartTimer(); // timer start + + NetManagerRegister(HOT_AP_NAME, FanNetEventHandler); + FanShowInfo(); + + FanLoop(); +} + +void FanDemoEntry(void) +{ + osThreadAttr_t attr; + attr.name = "FanTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = FAN_TASK_STACK_SIZE; + attr.priority = FAN_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)FanTask, NULL, &attr) == NULL) { + FANERR("Falied to create FanTask!\n"); + } +} + +SYS_RUN(FanDemoEntry); diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/keypad.c b/ScenarioDemos/SmartFanDevice/smartfan/src/keypad.c new file mode 100755 index 0000000000000000000000000000000000000000..7011b0d5de97d37617e863942247c16ac7b16892 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/keypad.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "iot_gpio.h" +#include "iot_errno.h" + +#include "peripheral_hal.h" +#include "keypad.h" +#include "defines.h" + +#include "ohos_types.h" + +#define ADC_TIME_COUNT 20 + +enum { + ADC_S0_MIN = 5, + ADC_S0_MAX = 228, + ADC_S1_MIN, + ADC_S1_MAX = 512, + ADC_S2_MIN, + ADC_S2_MAX = 854 +}; + +static KEY_CODE KeyPadGetKey(void) +{ + unsigned short data = 0; + if (HalAdcRead(HAL_WIFI_IOT_ADC_CHANNEL_2, &data, HAL_WIFI_IOT_ADC_EQU_MODEL_4, + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, ADC_TIME_COUNT) == 0) { + if ((ADC_S0_MIN <= data) && (data <= ADC_S0_MAX)) return KEY_PAD_MODE; + if ((ADC_S1_MIN <= data) && (data <= ADC_S1_MAX)) return KEY_PAD_UP; + if ((ADC_S2_MIN <= data) && (data <= ADC_S2_MAX)) return KEY_PAD_DOWN; + } + + return KEY_PAD_NONE; +} + +static void *KeyEventTask(const char *args) +{ + uint8 keycode = KEY_PAD_NONE; + keypad_event_call g_event_call = (keypad_event_call)args; + if (g_event_call == NULL) { + KEY_ERR("no key event call! \n"); + } + while (1) { + KEY_CODE key = KeyPadGetKey(); + if (keycode == key) { + osDelay(KEY_DELAY_TIME); + continue; + } + keycode = key; + if (keycode == KEY_PAD_NONE) { + osDelay(KEY_DELAY_TIME); + continue; + } + + if (g_event_call != NULL) { + KeyEvent e; + e.code = keycode; + e.value = 1; + g_event_call(&e); + } + } + + return NULL; +} + +int KeyRegisterInit(keypad_event_call gcall) +{ + osThreadAttr_t attr; + attr.name = "KeyEventTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = KEY_TASK_STACK_SIZE; + attr.priority = KEY_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)KeyEventTask, gcall, &attr) == NULL) { + KEY_ERR("Falied to create KeyEventTask! \n"); + } + + return 0; +} diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/oled.c b/ScenarioDemos/SmartFanDevice/smartfan/src/oled.c new file mode 100755 index 0000000000000000000000000000000000000000..4bca80868ccc280e1ce02bd6a6237e9e724eb051 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/oled.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "kal.h" +#include "iot_errno.h" +#include "iot_i2c.h" + +#include "oled.h" +#include "code_tab.h" + +#include "defines.h" + + +static uint8 OledInitCmd[CMD_LENGTH] = { + DISPLAY_OFF, // Display off + SET_LOW_COLUMN_ADDRESS, // ---set low column address + SET_HIGH_COLUMN_ADDRESS, // ---set high column address + SET_START_LINE_ADDRESS, // --set start line address + SET_PAGE_ADDRESS, // --set page address + CONTRACT_CONTROL, // contract control + FULL_SCREEN, // --128 + SET_SEGMENT_REMAP, // set segment remap + NORMAL, + SET_MULTIPLEX, // --set multiplex ratio(1 to 64) + DUTY, // --1/32 duty + SCAN_DIRECTION, // Com scan direction + DISPLAY_OFFSET, // -set display offset + DISPLAY_TYPE, + OSC_DIVISION, // set osc division + DIVISION, + COLOR_MODE_OFF, // set area color mode off + COLOR, + PRE_CHARGE_PERIOD, // set Pre-Charge Period + PERIOD, + PIN_CONFIGUARTION, // set com pin configuartion + CONFIGUARTION, + SET_VCOMH, // set Vcomh + VCOMH, + SET_CHARGE_PUMP_ENABLE, // set charge pump enable + PUMP_ENABLE, + TURN_ON_OLED_PANEL // --turn on oled panel +}; + + +/* I2C write Byte */ +static uint32 I2cWriteByte(uint8 regAddr, uint8 i2cData) +{ + uint32 status; + uint8 sendBuf[2]; + sendBuf[0] = regAddr; + sendBuf[1] = i2cData; + + status = IoTI2cWrite(WIFI_IOT_OLED_I2C_IDX_0, OLED_ADDRESS, sendBuf, sizeof(sendBuf)); + if (status != IOT_SUCCESS) { + OLED_ERR("===== Error: SSD1306 OLED Screen I2C write status = 0x%x! =====\r\n", status); + } + + return status; +} + +static uint32 WriteCmd(uint8 cmd) +{ + return I2cWriteByte(OLED_ADDRESS_WRITE_CMD, cmd); +} + +static uint32 WriteData(uint8 data) +{ + return I2cWriteByte(OLED_ADDRESS_WRITE_DATA, data); +} + +static void OledSetPosition(uint8 x, uint8 y) +{ + if (IOT_SUCCESS != WriteCmd(0xb0 + y)) { + OLED_ERR("WriteCmd Error \n"); + return; + } + + if (IOT_SUCCESS != WriteCmd(((x&0xf0)>>SET_POSITION_OFFSET) | 0x10)) { + OLED_ERR("WriteCmd Error \n"); + return; + } + + if (IOT_SUCCESS != WriteCmd(x & 0x0f)) { + OLED_ERR("WriteCmd Error \n"); + return; + } +} + +static void OledFillScreen(uint8 fii_data) +{ + for (uint8 m = 0; m < MAX_LINE_OF_LANTTICE; m++) { + if (IOT_SUCCESS != WriteCmd(0xb0 + m)) { + OLED_ERR("WriteCmd Error \n"); + return; + } + + if (IOT_SUCCESS != WriteCmd(0x00)) { + OLED_ERR("WriteCmd Error \n"); + return; + } + + if (IOT_SUCCESS != WriteCmd(0x10)) { + OLED_ERR("WriteCmd Error \n"); + return; + } + + for (uint8 n = 0; n < Max_Column; n++) { + if (IOT_SUCCESS != WriteData(fii_data)) { + OLED_ERR("WriteData Error \n"); + return; + } + } + } +} + +static void OledShowChar(uint8 x, uint8 y, uint8 chr, uint8 charSize) +{ + uint8 i; + uint8 c = chr - ' '; // calc the offset + + if (charSize == CHAR_SIZE_OF_LANTTICE_8_16) { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i ]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i + HORI_PIXEL_OF_LANTTICE_8_16]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][0][i]); + } + + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][1][i]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][0][i]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][1][i]); + } + } else { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_6_8; i++) { + WriteData(F6X8[c][i]); + } + } +} + +// oled init +int OledInit(void) +{ + uint32 status; + osDelay(DELAY_100_MS); // 100ms Keep the power supply stable. + + for (int i = 0; i < CMD_LENGTH; i++) { + status = WriteCmd(OledInitCmd[i]); + if (status != IOT_SUCCESS) { + OLED_ERR("Failed to write OledInitCmd: 0x%x \n", OledInitCmd[i]); + return IOT_FAILURE; + } + } + + OledFillScreen(0x00); // The screen off + + osDelay(DELAY_10_MS); // 10ms + OledShowStr("OpenHarmony OS", strlen("OpenHarmony OS"), HORIZONTAL_COORDINATE_OF_SLOGANS, + VERTICAL_COORDINATE_OF_SLOGANS, 1); + osDelay(DELAY_500_MS); // The time of keep display + OledShowStr(" ", strlen(" "), HORIZONTAL_COORDINATE_OF_SLOGANS, + VERTICAL_COORDINATE_OF_SLOGANS, 1); + + OLED_PRT("OledInit succuss\n"); + + return IOT_SUCCESS; +} + +void OledSetOnOff(int value) +{ + (void)value; +} + +void OledClear(void) +{ + OledFillScreen(0x00); // The screen off +} + +void OledShowStr(const char *str, int length, uint8 x, uint8 y, uint8 charSize) +{ + uint8 i; + if (str == NULL || length <= 0) { + OLED_ERR("no str to show! \n"); + return; + } + + if (x >= LIMIT_HORI_PIXEL) { + OLED_ERR("please input the correct x coord! \n"); + return; + } + + for (i = 0; i < length; i++) { + OledShowChar(x, y, str[i], charSize); + if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16 || charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + x += HORI_PIXEL_OF_LANTTICE_HZ_16_16; + } else { + x += HORI_PIXEL_OF_LANTTICE_8_16; + } + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/pwm.c b/ScenarioDemos/SmartFanDevice/smartfan/src/pwm.c new file mode 100755 index 0000000000000000000000000000000000000000..889b03967b6c971575c24a0bb672d9e98f2625a4 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/pwm.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "iot_gpio.h" +#include "iot_errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "ohos_types.h" + +#include "peripheral_hal.h" +#include "pwm.h" +#include "defines.h" + +static uint8 g_level = PWM_LEVEL_1; + + +static void *PwmProcess(const char *arg) +{ + (void)arg; + int delayTimes = 0; + + IoTGpioInit(WIFI_IOT_GPIO_IDX_2); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_2, IOT_IO_FUNC_GPIO); + IoTGpioSetDir(WIFI_IOT_GPIO_IDX_2, IOT_GPIO_DIR_OUT); + + while (1) { + if (g_level == PWM_LEVEL_0) { // when the PWM is set close + IoTGpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, GPIO_PIN_LOW); + osDelay(PWM_DELAY_TIME); + continue; + } + + if (g_level >= PWM_LEVEL_NBR) + g_level = PWM_LEVEL_1; + + IoTGpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, GPIO_PIN_HIGH); + delayTimes = PWM_DELAY_TIME / (PWM_LEVEL_NBR - g_level); + osDelay(delayTimes); + + IoTGpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, GPIO_PIN_LOW); + delayTimes = PWM_DELAY_TIME / g_level; + osDelay(delayTimes); + } +} + + +int PwmInit(void) +{ + osThreadAttr_t attr; + attr.name = "PwmProcess"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = PWM_TASK_STACK_SIZE; + attr.priority = PWM_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)PwmProcess, NULL, &attr) == NULL) { + PWM_ERR("Falied to create NanCfgNetTask!\n"); + return -1; + } + + return 0; +} + +void PwmSetLevel(PWM_LEVEL level) +{ + if (level >= 0 && level < PWM_LEVEL_NBR) + g_level = level; +} + +int PwmGetLevel(void) +{ + return g_level; +} diff --git a/ScenarioDemos/SmartFanDevice/smartfan/src/sensor.c b/ScenarioDemos/SmartFanDevice/smartfan/src/sensor.c new file mode 100755 index 0000000000000000000000000000000000000000..5ecbdff27eeb86c61b8728d9d651d61e317b9920 --- /dev/null +++ b/ScenarioDemos/SmartFanDevice/smartfan/src/sensor.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include + +#include "ohos_types.h" +#include "iot_errno.h" +#include "kal.h" +#include "sensor.h" +#include "defines.h" + +static uint32 SensorWrite(uint8 triggerCmd, uint8 highByteCmd, uint8 lowByteCmd) +{ + uint8 _send_user_cmd[AHT_SNED_CMD_LEN] = {triggerCmd, highByteCmd, lowByteCmd}; + + return IoTI2cWrite(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x00, _send_user_cmd, AHT_SNED_CMD_LEN); +} + +static uint32 SensorRead(uint8 type) +{ + uint8 recvData[AHT_REG_ARRAY_LEN] = {0}; + float temper = 0; + uint32 temper_t = 0; + + memset_s(&recvData, sizeof(recvData), 0x0, sizeof(recvData)); + + IoTI2cRead(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x01, recvData, AHT_REG_ARRAY_LEN); + if (type == AHT_TEMPERATURE) { + temper = (float)((recvData[AHT_REG_TEMP_BITS_1] &0x0f)<Open选择此项目; + +3)单击Build>BuildAPP(s)/Hap(s)>Build Debug Hap(s)编译hap软件包,单击Run>Run'entry运行hap包; + +4)在HarmonyOS系统手机上运行步骤3)编译成功的应用,则需要配置签名文件File>ProjectStructure>Project>SigningConfigs中配置签名,可直接勾选自动签名,后根据提示信息操作; + +##### 2.与设备端联动步骤 + +1)打开FA,在热点连接列表中找到Kettle_AP热点并连接,点击开始配网,选择好热点并输入密码点击确定给设备端配网; + +2)在设备端配网成功后,可控制设备开关机、设备不同的烧水模式、比如50度冲奶,80度泡茶,点击加热升至/煮沸降至 保温温度按钮,才是发送消息给设备端; + +3)并根据时间自动将加热到指定的温度,比如早上8点一杯温水,下午16点泡花茶80度水等;还能定时提醒主人喝水; + +### 约束限制 + +已实名认证的开发者联盟账号 ,具体参考:https://developer.huawei.com/consumer/cn/ + +开发工具:DevEcoStudio 2.2Beta1 参考: https://developer.harmonyos.com/cn/develop/deveco-studio#download + +•安装DevEco Studio + +设置DevEco Studio开发环境,DevEco Studio开发环境需要连接到网络,以确保该正常使用。 + +可以根据以下两种情况配置开发环境: + +1.如果您可以直接访问Internet,则只需下载HarmonyOS SDK + +2.如果网络无法直接访问Internet,则可以通过代理服务器进行访问 • 生成密钥并申请证书 + +具体环境搭建请参考: https://developer.harmonyos.com/cn/docs/documentation/doc-guides/installation_process-0000001071425528 + +更多资料请登录鸿蒙应用开发官网: https://developer.harmonyos.com/cn/ + diff --git a/ScenarioDemos/SmartKettleApp/build.gradle b/ScenarioDemos/SmartKettleApp/build.gradle new file mode 100755 index 0000000000000000000000000000000000000000..a787701a4467429b113d9ad335d99a032da408f1 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/build.gradle @@ -0,0 +1,38 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + classpath 'com.huawei.ohos:decctest:1.2.4.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/build.gradle b/ScenarioDemos/SmartKettleApp/entry/build.gradle new file mode 100755 index 0000000000000000000000000000000000000000..9ab5cc88a54b2dc3cec36107739795603b572870 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' +} +decc { + supportType = ['html','xml'] +} diff --git a/ScenarioDemos/SmartKettleApp/entry/node_modules/fa-softaputil.js b/ScenarioDemos/SmartKettleApp/entry/node_modules/fa-softaputil.js new file mode 100755 index 0000000000000000000000000000000000000000..9a47499a5b4fdda8da95ccc66479fd6eeeb6a866 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/node_modules/fa-softaputil.js @@ -0,0 +1,72 @@ +// @ts-nocheck +const injectRef = Object.getPrototypeOf(global) || global +injectRef.regeneratorRuntime = require('@babel/runtime/regenerator') +const CONSTANT = { + BUNDLE_NAME: "ohos.samples.smartkettle", + ABILITY_NAME_FOR_BM: "ohos.samples.smartkettle.ControlAbility", + ABILITY_NAME_FOR_MAIN: "ohos.samples.smartkettle.MainAbility", + ABILITY_NAME_FOR_CONTROLSERVICE: "ohos.samples.smartkettle.ControlServiceAbility", + TAG:"[Demo]:" +} + +const ABILITY_TYPE_EXTERNAL = 0; +const ABILITY_TYPE_INTERNAL = 1; +const ACTION_SYNC = 0; +const ACTION_ASYNC = 1; + +var FASoftapUtil = { + info: function (info) { + console.info(CONSTANT.TAG + info); + }, + + // Call PA to send command + sendMessage:async function(data, code){ + var action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + action.abilityName = CONSTANT.ABILITY_NAME_FOR_CONTROLSERVICE; + action.messageCode = code; + action.data = data; + action.abilityType = ABILITY_TYPE_EXTERNAL; + action.syncOption = ACTION_SYNC; + var result = await FeatureAbility.callAbility(action); + return result; + }, + + // Pull up FA + callNewFa: async function (dataInfo, flag) { + var action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + //action.deviceType = 1; + if (flag === 0) { + action.abilityName = CONSTANT.ABILITY_NAME_FOR_BM; + } else if (flag === 1) { + action.abilityName = CONSTANT.ABILITY_NAME_FOR_MAIN; + } + action.data = dataInfo; + await FeatureAbility.startAbility(action); + }, + + subscribe: async function (code, callback){ + let action = {}; + action.bundleName = CONSTANT.BUNDLE_NAME; + action.abilityName = CONSTANT.ABILITY_NAME_FOR_CONTROLSERVICE; + action.messageCode = code; + action.abilityType = ABILITY_TYPE_EXTERNAL; + action.syncOption = ACTION_SYNC; + + var result = await FeatureAbility.subscribeAbilityEvent(action, function(callbackData) { + callback(callbackData); + }); + var ret = JSON.parse(result); + if (ret.code == 0) { + console.info('subscribe success, result:' + result); + } else { + console.error('subscribe error, result:' + result); + } + console.info('==Trash==subscribe---end---'); + } +}; + +module.exports = { + FASoftapUtil +}; \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/node_modules/fan-constants.js b/ScenarioDemos/SmartKettleApp/entry/node_modules/fan-constants.js new file mode 100755 index 0000000000000000000000000000000000000000..4fe17859ea65b15c66d202e3da4962993016550a --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/node_modules/fan-constants.js @@ -0,0 +1,12 @@ +const CONSTANTS = { + CONTROL_CODE: 1001, + GET_CURRENT_WIFI_CODE: 2001, + SET_WIFI_CODE: 2002, + GET_AVAILABLE_WIFI_CODE: 2003, + SUBSCRIBE_CONTROL_STATE: 3001, + SMARTFAN_WIFI: "Kettle_AP" +} + +module.exports = { + CONSTANTS +}; \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/config.json b/ScenarioDemos/SmartKettleApp/entry/src/main/config.json new file mode 100755 index 0000000000000000000000000000000000000000..1dd1f06b535742a7e1dd25656c8c2da08bf9436d --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/config.json @@ -0,0 +1,122 @@ +{ + "app": { + "bundleName": "ohos.samples.smartkettle", + "vendor": "sample", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.smartkettle", + "name": ".MyApplication", + "mainAbility": "ohos.samples.smartkettle.MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "metaData": { + "customizeData": [ + { + "name": "hwc-theme", + "value": "androidhwext:style/Theme.Emui.Translucent.NoTitleBar" + } + ] + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "ohos.samples.smartkettle.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + }, + { + "visible": true, + "name": "ohos.samples.smartkettle.ControlAbility", + "icon": "$media:icon", + "description": "$string:controlability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + }, + { + "name": "ohos.samples.smartkettle.ControlServiceAbility", + "icon": "$media:icon", + "description": "$string:controlserviceability_description", + "type": "service" + } + ], + "js": [ + { + "pages": [ + "pages/index/index", + "pages/phone/index", + "pages/otherWifi/index", + "pages/confignet/index", + "pages/locationset/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + }, + { + "pages": [ + "pages/device/index", + "pages/reminder/index", + "pages/interval/index", + "pages/timer/index", + "pages/service/index" + ], + "name": "control", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ], + "reqPermissions": [ + { + "name": "ohos.permission.INTERNET" + }, + { + "name": "ohos.permission.GET_WIFI_INFO" + }, + { + "reason": "get Local Location", + "name": "ohos.permission.LOCATION", + "usedScene": { + "ability": [ + "ohos.samples.smartkettle.MainAbility", + "ohos.samples.smartkettle.ControlAbility", + "ohos.samples.smartkettle.ControlServiceAbility" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.SET_WIFI_INFO" + } + ] + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java new file mode 100755 index 0000000000000000000000000000000000000000..ff324d124776bd2a3c40018d5722a81a21a87cdb --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/Const.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +public class Const { + + public static final String APP_NAME = "ohos.samples.smartkettle"; + public static final String IP = "192.168.5.1"; + +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java new file mode 100755 index 0000000000000000000000000000000000000000..4625d9cb3f0357d8f4a4d145d8fc808f4604c49b --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlAbility.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.content.Intent; +import ohos.aafwk.content.IntentParams; +import ohos.ace.ability.AceAbility; +import ohos.utils.zson.ZSONObject; + +public class ControlAbility extends AceAbility { + private final static String TAG = "[Demo]:ControlAbility"; + + @Override + public void onStart(Intent intent) { + try { + // Start the current ability using Full mode, 2 means Full mode when FeatureAbility start. + intent.setParam("window_modal", 2); + + // Start control FeatureAbility. + setInstanceName("control"); + + String data = ZSONObject.toZSONString(intent); + LogUtil.info(TAG, "data==" + data); + + + // JS pull up this FeatureAbility , __startParams means default ability pull up control ability + Object reBackObj = intent.getParams().getParam("__startParams"); + + // Get dataInfo value sessionId and set to control page. + if (reBackObj != null) { + ZSONObject reBackInfo = ZSONObject.stringToZSON((String) reBackObj); + String dataInfo = reBackInfo.getString("serverIp"); + LogUtil.info(TAG, "dataInfo = " + dataInfo); + if (dataInfo != null) { + setParams(intent, "dataInfo", dataInfo); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + super.onStart(intent); + } + + @Override + public void onStop() { + + super.onStop(); + } + + private void setParams(Intent intent, String tag, String tagInfo) { + try { + IntentParams intentParams = intent.getParams(); + if (intentParams != null) { + intentParams.setParam(tag, tagInfo); + // Set params to control FeatureAbility home page. + setPageParams(null, intentParams); + + } + }catch (Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServiceAbility.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServiceAbility.java new file mode 100755 index 0000000000000000000000000000000000000000..87e8367c1d99a4fd64d75862c2b7d535cac8275b --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/ControlServiceAbility.java @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.rpc.IRemoteBroker; +import ohos.rpc.IRemoteObject; +import ohos.rpc.MessageOption; +import ohos.rpc.MessageParcel; +import ohos.rpc.RemoteException; +import ohos.rpc.RemoteObject; +import ohos.utils.zson.ZSONArray; +import ohos.utils.zson.ZSONObject; +import ohos.wifi.WifiDevice; +import ohos.wifi.WifiLinkedInfo; +import ohos.wifi.WifiScanInfo; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.Socket; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/* + * PA response interface call, used to obtain wifi, call socket tcp to control the device + */ +public class ControlServiceAbility extends Ability { + private final static String TAG = "[Demo]:ControlServiceAbility"; + + private static final int SUCCESS = 200; + private static final int ERROR = 1; + private static final int GET_CURRENT_WIFI_CODE = 2001; + private static final int GET_AVAILABLE_WIFI_CODE = 2003; + private static final int SET_WIFI_CODE = 2002; + private static final int CONTROL_CODE = 1001; + private static final int SUBSCRIBE_CONTROL_STATE = 3001; + + private MyRemote remote = new MyRemote(); + + private int controlPort = 8787; + + private int configNetPort = 8686; + + private Socket socketDeviceListener = null; + + private IRemoteObject controlStateRemoteObj = null; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + } + + + @Override + public void onBackground() { + super.onBackground(); + } + + @Override + public void onStop() { + super.onStop(); + if (socketDeviceListener != null) { + try { + socketDeviceListener.close(); + socketDeviceListener = null; + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void onCommand(Intent intent, boolean restart, int startId) { + } + + @Override + public void onDisconnect(Intent intent) { + } + + @Override + protected IRemoteObject onConnect(Intent intent) { + super.onConnect(intent); + return remote.asObject(); + } + + class MyRemote extends RemoteObject implements IRemoteBroker { + MyRemote() { + super("ControlServiceAbility_MyRemote"); + } + + @Override + public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) { + Map result = new HashMap(); + String dataStr = data.readString(); + LogUtil.info("onRemoteRequest: code=", String.valueOf(code) + ";data=" + dataStr); + switch (code) { + // controlling device + case CONTROL_CODE: { + try { + reply.writeString(controlDevice(dataStr)); + break; + } catch (IOException e) { + e.printStackTrace(); + LogUtil.error(TAG, e.getMessage()); + result.put("code", ERROR); + result.put("errMsg", e.getMessage()); + reply.writeString(ZSONObject.toZSONString(result)); + return false; + } + } + // Get current wifi + case GET_CURRENT_WIFI_CODE: + // Get WLAN management objects + reply.writeString(getCurrentWifi()); + break; + // Get available wifi + case GET_AVAILABLE_WIFI_CODE: + reply.writeString(getAvialableWifi()); + break; + // Distribution network + case SET_WIFI_CODE: + try { + reply.writeString(configNet(dataStr)); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case SUBSCRIBE_CONTROL_STATE: { + // If only single FA subscription is supported, it can be directly covered: + controlStateRemoteObj = data.readRemoteObject(); + result.put("code", 0); + reply.writeString(ZSONObject.toZSONString(result)); + break; + } + default: { + result.put("code", ERROR); + result.put("errMsg", "Invalid code :" + code); + reply.writeString(ZSONObject.toZSONString(result)); + return false; + } + } + return true; + } + + @Override + public IRemoteObject asObject() { + return this; + } + } + + /** + * Get available wifi + * + * @return + */ + private String getAvialableWifi() { + // Get WLAN management objects + WifiDevice wifiDevice = WifiDevice.getInstance(this); + // Call the WLAN scanning interface + try { + boolean isScanSuccess = wifiDevice.scan(); + if (isScanSuccess == false) { + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put("code", ERROR); + jsonObj.put("errMsg", "Fail to getAvialableWifi scan result false"); + return jsonObj.toString(); + } + // Call to get scan results + List scanInfos = wifiDevice.getScanInfoList(); + + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put("code", SUCCESS); + ZSONArray wifiArray = new ZSONArray(); + + Map result = new HashMap(); + // Take the BSSID as the dimension, so ssid is needed to remove duplicates + Set wifiSet = new HashSet<>(); + ohos.global.resource.ResourceManager resManager = this.getResourceManager(); + for (WifiScanInfo scanInfo : scanInfos) { + if (scanInfo.getSsid() == null || scanInfo.getSsid().trim().equals("") || + wifiSet.contains(scanInfo.getSsid())) { + continue; + } + ZSONObject jsonWifi = new ZSONObject(); + jsonWifi.put("ssid", scanInfo.getSsid()); + if (scanInfo.getSecurityType() == 0) { + jsonWifi.put("security", + this.getResourceManager().getElement(ResourceTable.String_forpublic).getString()); + } else { + jsonWifi.put("security", + this.getResourceManager().getElement(ResourceTable.String_encrypt).getString()); + } + wifiSet.add(scanInfo.getSsid()); + wifiArray.add(jsonWifi); + } + jsonObj.put("wifi", wifiArray); + return ZSONObject.toZSONString(jsonObj); + } catch (Exception e) { + ZSONObject jsonObj = new ZSONObject(); + jsonObj.put("code", ERROR); + jsonObj.put("errMsg", "Fail to getAvialableWifi" + e.getMessage()); + LogUtil.error("aaaaa fail to getAvialableWifi", e.getMessage()); + return jsonObj.toString(); + } + } + + /** + * controlling device + * + * @param dataStr The json string passed in from the front end, including the device serverIp + * @return Device response + * @throws IOException e + */ + private String controlDevice(String dataStr) throws IOException { + LogUtil.info(TAG, "=============" + dataStr); + + Map result = new HashMap(); + ZSONObject obj = ZSONObject.stringToZSON(dataStr); + // Device IP obtained using the interface + String serverIp = obj.getString("serverIp"); + LogUtil.info(TAG, "=============" + serverIp); + obj.remove("serverIp"); + Socket socket = new Socket(serverIp, controlPort); + dataStr = obj.toString(); + OutputStream out = socket.getOutputStream(); + out.write(dataStr.getBytes("UTF-8") ); + + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String str = in.readLine(); + in.close(); + LogUtil.info("onRemoteRequest controlDevice receive:", str); + socket.close(); + + if (socketDeviceListener == null) { + // Initialize device monitoring + initDeviceListener(serverIp); + } + // The returned result currently only supports String. For complex structures, + // it can be serialized as a ZSON string and reported + result.put("code", SUCCESS); + return ZSONObject.toZSONString(result); + } + + /** + * Get the currently connected wifi name + * + * @return name + */ + private String getCurrentWifi() { + WifiDevice wifiDevice = WifiDevice.getInstance(getContext()); + // Call the WLAN connection status interface to determine whether the current device is connected to WLAN + boolean isConnected = wifiDevice.isConnected(); + if (isConnected) { + // Get Wi-Fi connection information + Optional linkedInfo = wifiDevice.getLinkedInfo(); + // Get the SSID in the connection information + String ssid = linkedInfo.get().getSsid(); + return ssid; + } else { + return ""; + } + } + + /** + * Call socket to complete network configuration + * + * @param dataStr wifi account and password + * @return return + */ + private String configNet(String dataStr) throws IOException { + Socket socket = null; + OutputStream out = null; + BufferedReader in = null; + try { + // Fixed use on the device side192.168.10.1 + socket = new Socket(Const.IP, configNetPort); + out = socket.getOutputStream(); + out.write(dataStr.getBytes("UTF-8")); + + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String str = in.readLine(); + LogUtil.info("configNet receive:", str); + + return str; + } catch (IOException e) { + e.printStackTrace(); + LogUtil.error("configNet:", e.getMessage()); + return String.format("{\"code\":500,\"errmsg\":\"%s\"}", e.getMessage()); + } + finally { + socket.close(); + out.close(); + in.close(); + } + } + + /** + * Initialize the device to monitor, + * send 0xff, 0x55, 0xaa, 0x55, 0x00 to tell the device to use this connection to feedback the status + * + * @param serverIp serverIp + */ + private void initDeviceListener(String serverIp) { + if (serverIp == null || serverIp == "") { + return; + } + try { + socketDeviceListener = new Socket(serverIp, controlPort); + OutputStream out = socketDeviceListener.getOutputStream(); + byte[] cmds = {(byte) 0xff, (byte) 0x55, (byte) 0xaa, (byte) 0x55, (byte) 0x00}; + out.write(cmds); + + BufferedReader in = new BufferedReader(new InputStreamReader(socketDeviceListener.getInputStream())); + DeviceControlThread deviceControlThread = new DeviceControlThread(in); + deviceControlThread.start(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Thread monitoring device report + */ + class DeviceControlThread extends Thread { + private BufferedReader input; + + DeviceControlThread(BufferedReader in) { + this.input = in; + } + + @Override + public void run() { + try { + while (true) { + String str = this.input.readLine(); + LogUtil.info("initDeviceListener controlDevice receive:", str); + if (controlStateRemoteObj != null) { + LogUtil.info("initDeviceListener controlDevice success send111:", ""); + MessageParcel data = MessageParcel.obtain(); + MessageParcel reply = MessageParcel.obtain(); + MessageOption option = new MessageOption(); + data.writeString(ZSONObject.toZSONString(str)); + controlStateRemoteObj.sendRequest(100, data, reply, option); + LogUtil.info("initDeviceListener controlDevice success send22:", ""); + + } + } + } catch (IOException | RemoteException e) { + e.printStackTrace(); + LogUtil.error("initDeviceListener controlDevice receive:", e.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java new file mode 100755 index 0000000000000000000000000000000000000000..9156f53d046b5aacaaa95b02d60e373d1fe0a85f --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/LogUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.Locale; + +public class LogUtil { + private static final String TAG_LOG = ""; + + private static final int DOMAIN_ID = 0xD000F00; + + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, DOMAIN_ID, LogUtil.TAG_LOG); + + private static final String LOG_FORMAT = "%{public}s: %{public}s"; + + private static final boolean DEBUG = true; + + private LogUtil() { + } + + /** + * Print debug log + * + * @param tag log tag + * @param msg log message + */ + public static void debug(String tag, String msg) { + if (DEBUG) { + HiLog.debug(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print info log + * + * @param tag log tag + * @param msg log message + */ + public static void info(String tag, String msg) { + if (DEBUG) { + HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print warn log + * + * @param tag log tag + * @param msg log message + */ + public static void warn(String tag, String msg) { + if (DEBUG) { + HiLog.warn(LABEL_LOG, LOG_FORMAT, tag, msg); + } + } + + /** + * Print error log + * + * @param tag log tag + * @param msg log message + */ + public static void error(String tag, String msg) { + if (DEBUG) { + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, msg); + } + + } + + public static void error(String tag, final String format, Object... args) { + if (DEBUG) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } + } + + public static void info(String tag, final String format, Object... args) { + if (DEBUG) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java new file mode 100755 index 0000000000000000000000000000000000000000..d38584b2b7f0637390d98f17c66bcb30b63a058f --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MainAbility.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.smartkettle; + +import ohos.aafwk.content.Intent; +import ohos.ace.ability.AceAbility; + + +public class MainAbility extends AceAbility { + + /** + * This is the default FeatureAbility entrance. + * + * @since 2021-01-19 + */ + @Override + public void onStart(Intent intent) { + // Start the current ability using half mode, 3 means pop-up mode when FeatureAbility start. + intent.setParam("window_modal", 3); + + // Start default FeatureAbility. + setInstanceName("default"); + this.requestPermissionsFromUser(new String[]{ohos.security.SystemPermission.LOCATION}, 0); + + super.onStart( intent ); + + } + + @Override + public void onStop() { + + super.onStop(); + } + +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java new file mode 100755 index 0000000000000000000000000000000000000000..f49f79ca0f7f42257f45bb0b75a1032c4d59e4ac --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/java/ohos/samples/smartkettle/MyApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/app.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/app.js new file mode 100755 index 0000000000000000000000000000000000000000..f7e24e3f9b82815f93cc6192520ec42cdd229106 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/app.js @@ -0,0 +1,106 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +export default { + onCreate() { + console.info('AceApplication onCreate') + }, + onDestroy() { + console.info('AceApplication onDestroy'); + }, + onInit(){ + }, + // The ServerIp after the device is successfully configured + ServerIp:"", + + AlarmList: [ + { + message: '', + hour: "08", + min: "00", + temp: "50", + state: 1 + }, + { + message: '', + hour: "13", + min: "30", + temp: "50", + state: 1 + }, + { + message: '', + hour: "16", + min: "00", + temp: "50", + state: 1 + }, + { + message: '', + hour: "18", + min: "00", + temp: "90", + state: 1 + } + ], + MessageList: [ + { + hour: "09", + min: "00", + state: 1 + }, + { + hour: "11", + min: "30", + state: 1 + }, + { + hour: "15", + min: "00", + state: 1 + }, + { + hour: "17", + min: "00", + state: 1 + } + ], + IntervalList: [ + { + hour: "09", + min: "00", + state: 1 + }, + ], + defModeValue: [ + { + textValue: "+", + tpValue: "", + }, + + { + textValue: "+", + tpValue: "" + }, + { + textValue: "+", + tpValue: "" + }, + { + textValue: "+", + tpValue: "" + }, + ], +}; diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/css/common.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/css/common.css new file mode 100755 index 0000000000000000000000000000000000000000..e3a2e1db67e3c7124a4031f2be29bf69b71f7fe6 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/css/common.css @@ -0,0 +1,179 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.flexcol { + flex-direction: column; +} +.flexrow { + flex-direction: row; +} +.jstart { + justify-content: flex-start; +} +.jcenter { + justify-content: center; +} +.jspacebe{ + justify-content: space-between; +} +.jspacearound{ + justify-content: space-around; +} +.astart { + align-items: flex-start; +} +.acenter { + align-items: center; +} +.color_black { + color: #000000; +} +.color_gray { + color: #969ca1; +} +.color_white{ + color: #ffffff; +} + +.color_yellow{ + color: #ff9600; +} + +.text_black{ + text-color: #000000; +} +.color_blue { + color: #007dff; +} +.back_blue { + background-color: #007dff; +} +.back_color { + background-color: #f7f7f7; +} + +.back_white{ + background-color: #ffffff; +} + +.back_yellow{ + background-color: #ff9600; +} +.font25{ + font-size: 25px; +} +.font30 { + font-size: 30px; +} + +.font35 { + font-size: 35px; +} + +.font40{ + font-size: 40px; +} +.font45 { + font-size: 45px; +} +.font70 { + font-size: 70px; +} + +.mleft32 { + margin-left: 32px; +} + +.mright32 { + margin-right: 32px; +} +.mtop20{ + margin-top: 20px; +} + +.mbottom20{ + margin-bottom: 20px; +} +.mtop40{ + margin-top: 40px; +} + +.mbottom40{ + margin-bottom: 40px; +} + +.borradius16{ + border-radius: 16px; +} +.text_center { + align-content: center; + text-align: center; +} + +.flexux{ + width: 720px; + height: 200px; + margin-bottom: 30px; + margin-top: 30px; +} +.modeux { + margin-left: 64px; +} + +.flexpart{ + flex-direction: row; + justify-content: space-around; + align-items: center; +} + +.imageux{ + width: 60px; + height: 60px; + margin-right: 20px; +} +.titleux { + margin-top: 20px; + margin-bottom: 30px; + color: #000000; + font-size: 45px; +} +.saveux { + margin-top: 10px; + color: #007dff; + font-size: 35px; +} + +.circle{ + margin-top: 20px; + margin-bottom: 20px; + background-color: #ffffff; + icon-width:70px; + icon-height: 70px; + radius:72px; +} +.dialogdiv { + flex-direction: column; + align-items: flex-start; + width: 625px; + height: 350px; +} + +.input { + width: 525px; + height: 100px; + margin-left: 50px; + margin-top: 10px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/BG.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/BG.png new file mode 100755 index 0000000000000000000000000000000000000000..d2dd96f68f2d5e00f31f63c07d7fbe402fd50b96 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/BG.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png new file mode 100755 index 0000000000000000000000000000000000000000..f488f9adbaa27a1425b8b91b251b89de8c02bc0b Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ID_pic.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png new file mode 100755 index 0000000000000000000000000000000000000000..fca20b16675af33f169e667c358bd70d5c9ab365 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_banner.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png new file mode 100755 index 0000000000000000000000000000000000000000..4dcf71ba67b8bb0b20698defc320382b181a69c0 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_off.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png new file mode 100755 index 0000000000000000000000000000000000000000..725aa889ef7d728b203de5a50afca79e202eb972 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_selected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png new file mode 100755 index 0000000000000000000000000000000000000000..cdbcc82696f4a7dc88b0cce8320710453b4f4333 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_coffee_unselected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png new file mode 100755 index 0000000000000000000000000000000000000000..b548f108645d5b6feb628ea2b4645cdf770c03a4 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_increase.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png new file mode 100755 index 0000000000000000000000000000000000000000..d03fa7e2bae8b17b4571595a23ae6402ec3e9ce8 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_off.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png new file mode 100755 index 0000000000000000000000000000000000000000..ead98d86476c984f15b04e6ae9167f8c23b36e1d Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_selected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png new file mode 100755 index 0000000000000000000000000000000000000000..5f3707285beeea6807341f8e13bfb7f20f55ecad Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_milk_unselected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png new file mode 100755 index 0000000000000000000000000000000000000000..eb21df3f021b20fca0b121234cce27c2a153130b Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_off.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png new file mode 100755 index 0000000000000000000000000000000000000000..4c8756de7c6ed8e3aa7faf89d9971b4bab29fec9 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_selected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png new file mode 100755 index 0000000000000000000000000000000000000000..5f49851719d7625bf6bc148cec5a9380b8c9d143 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_tea_unselected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png new file mode 100755 index 0000000000000000000000000000000000000000..5d96c0dfad695d58c006bbd9810729aaacc04f2f Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_timing_task.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png new file mode 100755 index 0000000000000000000000000000000000000000..830e926aa1654a634f1f1a1341e0a2111736c880 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_off.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png new file mode 100755 index 0000000000000000000000000000000000000000..b1349dbbb4ebf526987f33f523445e371114ff7c Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_selected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png new file mode 100755 index 0000000000000000000000000000000000000000..b152bc4e8183481564c6408c45cf6709b73c910a Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/home_icon_water_unselected.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png new file mode 100755 index 0000000000000000000000000000000000000000..d2455f80e26f40883b7130e61333769d5cc20778 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_off.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png new file mode 100755 index 0000000000000000000000000000000000000000..570a578448e37d74569458eb9bf9fa1fe193f157 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/ic_power_on.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png new file mode 100755 index 0000000000000000000000000000000000000000..3e1e3cd4035e07b70eb09ed39e8f104c51b4a3af Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_alarm_clock.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png new file mode 100755 index 0000000000000000000000000000000000000000..5f0c565c85816201c27be59d36071773cb0f4b43 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png new file mode 100755 index 0000000000000000000000000000000000000000..4f07888fb6d0b1fd72b445d0312e8db4acf15837 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_back_white.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png new file mode 100755 index 0000000000000000000000000000000000000000..3bea9cb29852d10cc591f4d4b8d649168fddb420 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_plus.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png new file mode 100755 index 0000000000000000000000000000000000000000..be2d79e6456fcadf3ec763b3cfc565a6be857910 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_toward.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png new file mode 100755 index 0000000000000000000000000000000000000000..1be7c1549102f9191c8c16dc1f0f4e2efcb6d8cb Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/icon_water_clock.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png new file mode 100755 index 0000000000000000000000000000000000000000..46f28eee6ef36cde7043e784e2c984e0575d9ff9 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/net_success.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png new file mode 100755 index 0000000000000000000000000000000000000000..0ba364e33f7760e153cef273338572127b4d6f5f Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/start_notice.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png new file mode 100755 index 0000000000000000000000000000000000000000..94643ba39483933f0bb7086fa4230d8712a0f909 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water notice _icon_turn.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png new file mode 100755 index 0000000000000000000000000000000000000000..64a5e5efb8718542ed06b62a4e22add5be06ddc1 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/img/water_notice.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css new file mode 100755 index 0000000000000000000000000000000000000000..5bfcf83f495959ebf7f20f3701dfd54703c6743d --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.css @@ -0,0 +1,41 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../css/common.css'; +.device_img { + width: 304px; + height: 304px; +} + +.device_img_fullWindow { + width: 356px; + height: 356px; +} + +.mleft10{ + margin-left: 10px; +} + +.mtop10{ + margin-top: 10px; +} + +.marginother{ + margin-top: 0px; +} +.icon{ + width: 50px; + height: 50px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml new file mode 100755 index 0000000000000000000000000000000000000000..472a04bdaabe4291ef1fc9850428ea275226ca47 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.hml @@ -0,0 +1,37 @@ + + +
+
+
+ +
+ {{device_name}} + +
+ {{text_icon}} +
+
+ + {{neting_value}} + +
+
+ + {{success_value}} + +
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js new file mode 100755 index 0000000000000000000000000000000000000000..77792e0288acec39d6c5ff103e550f97307812b7 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/header/header.js @@ -0,0 +1,34 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import app from '@system.app'; +export default{ + props: [ + 'device_name', + 'device_icon', + 'is_full', + 'os_icon', + 'text_icon', + 'home_icon', + + 'neting_state', + 'neting_value', + 'success_state', + 'success_icon', + 'success_value', + + ], + +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css new file mode 100755 index 0000000000000000000000000000000000000000..19da9acd4c05b146191e5704887b27db8371956b --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.css @@ -0,0 +1,17 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +@import '../../css/common.css'; + + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml new file mode 100755 index 0000000000000000000000000000000000000000..c91468eb61c5ece6372c13b93ff3e39e090ac0be --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{title_text}} +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js new file mode 100755 index 0000000000000000000000000000000000000000..6726caf8559c8552d767d25112ddf7501125ac8b --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/setting/setting.js @@ -0,0 +1,26 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import app from '@system.app'; +export default { + props: [ + 'back_src', + 'title_text', + + ], + returnBack(){ + app.terminate(); + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css new file mode 100755 index 0000000000000000000000000000000000000000..6b3997795f432953de0b96cce534b122809d14d6 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.css @@ -0,0 +1,15 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +@import '../../css/common.css'; \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml new file mode 100755 index 0000000000000000000000000000000000000000..28633350ef02459068fcccdc6df69f1092d801be --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.hml @@ -0,0 +1,22 @@ + + +
+
+ + {{title_text}} + {{save_text}} +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js new file mode 100755 index 0000000000000000000000000000000000000000..5d657c72e77bee05d2e1eb741d68b60615cb265e --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/common/pages/title/title.js @@ -0,0 +1,28 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'img_src', + 'title_text', + 'save_text', + 'save' + ], + returnBack(){ + router.back(); + }, +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json new file mode 100755 index 0000000000000000000000000000000000000000..dda45b22fc935e66674eb6c0bb663807ac0a85dc --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/en-US.json @@ -0,0 +1,91 @@ +{ + "strings": { + "deviceName": "SmartKettle", + "logoName": "CPlogo", + "netingValue": "DistributionNetworkIsInProgress..", + "successValue": "DistributionNetworkSuccess", + "holdingTemperature": "HoldingTemperature", + "25temperature": "25℃", + "50temperature": "50℃", + "80temperature": "80℃", + "99temperature": "99℃", + "warmWater": "Drinking", + "milk":"Milk", + "tea": "Tea", + "boilingWater": "Boiled", + "holdingTime": "KeepTime", + "keepWarm": "AutoKeep", + "more": "More", + "down": "BoilToHoldingTemperature", + "up": "HeatingToHoldingTemperature", + "autoSet": "AutomationSettings", + "ServiceRecommond": "ServiceRecommendation", + "setted": "YouSet“", + "running": "“StartRunning", + "tips": "EnterAName(NoMoreThan6Words)", + "alarmClock": "SetScheduledTasks", + "waterClock": "SetWaterReminder", + "setName": "EnterName", + "100temperature": "100℃", + "warm": "ACupOfWarmWaterInTheMorning", + "feeding": "GiveTheBreastToOne'sBaby", + "afternoonTea":"BeautyAfternoonTea", + "gingerTea": "BrownSugarGingerTea", + "noMore24": "CannotExceed24,SetTo00", + "noMore60": "CannotExceed60,SetTo00", + "noMore100": "CannotExceed100,SetTo100", + "startTime": "StartTime", + "endTime": "EndTime", + "opened": "On", + "closed": "Off", + "drinkWater": "It'sTimeToDrink", + "waterBoiled": "~~Master,TheWaterIsBoiling~~", + "heating": "Heating", + "keepingWarm": "Keeping", + "failedAccept": "FailedToAcceptMessage", + "failedSend": "FailedToSendMessage", + "timedTask":"TimedTask", + "logging":"Logging", + "dailyExecution": "DailyExecution", + "input": "PleaseEnter...", + "hour": "Hour", + "minute":"Minute", + "temperature": "Temperature", + "cancle":"Cancel", + "buttonOk": "Determine", + "repairservice": "MaintenanceService", + "service": "PersonalService", + "amount": "¥100", + "serviceTime": "Time", + "time": "Wednesday", + "contact": "ContactTheMerchant", + "buyNow": "BuyNow", + "drinkReminder": "WaterClock", + "save": "Save", + "modeSelect": "ModeSelection", + "timing": "Timing", + "interval": "Interval", + "setTime": "SetTimePoint", + "edit": "Edit", + "IntervalLength": "IntervalDuration", + "hours": "h", + "12hours": "12h" + + }, + "files": { + "backSrc": "/common/img/icon_back.png", + "deviceIcon": "/common/img/ID_pic.png", + "successIcon": "/common/img/net_success.png", + "homeBanner": "/common/img/home_banner.png", + "timingTask": "/common/img/home_icon_timing_task.png", + "iconAlarm": "/common/img/icon_alarm_clock.png", + "iconWater": "/common/img/icon_water_clock.png", + "startNotice": "/common/img/start_notice.png", + "waterNotice": "/common/img/water_notice.png", + "iconSrc": "common/img/icon_plus.png", + "serviceBack": "/common/img/BG.png", + "returnImg": "/common/img/icon_back_white.png", + "towardImg":"/common/img/icon_toward.png", + "turnOnImg": "/common/img/water notice _icon_turn.png" + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json new file mode 100755 index 0000000000000000000000000000000000000000..1e6782999a26dc9b93c7b6942ba7ae3d03620d87 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/i18n/zh-CN.json @@ -0,0 +1,91 @@ +{ + "strings": { + "deviceName": "智能恒温水壶", + "logoName": "CPlogo", + "netingValue": "正在配网,您可以进行部分控制", + "successValue": "配网成功", + "holdingTemperature": "保温温度", + "25temperature": "25℃", + "50temperature": "50℃", + "80temperature": "80℃", + "99temperature": "99℃", + "warmWater": "直饮", + "milk":"冲奶", + "tea": "茶饮", + "boilingWater": "开水", + "holdingTime": "保温时长", + "keepWarm": "自动保温", + "more": "查看更多", + "down": "煮沸降至保温温度", + "up": "加热升至保温温度", + "autoSet": "自动化设置", + "ServiceRecommond": "服务推荐", + "setted": "您设定的“", + "running": "“开始运行", + "tips": "输入名称(不超过6个字)", + "alarmClock": "设置定时任务", + "waterClock": "设置喝水提醒", + "setName": "输入名称", + "100temperature": "100℃", + "warm": "早上一杯温水", + "feeding": "给孩子喂奶", + "afternoonTea":"养颜下午茶", + "gingerTea": "红糖姜茶", + "noMore24": "不能超过24,设置为00", + "noMore60": "不能超过60.设置为00", + "noMore100": "不能超过100.设置为100", + "startTime": "开始时间", + "endTime": "结束时间", + "opened": "已开启", + "closed": "已关闭", + "drinkWater": "主人到了喝水时间了", + "waterBoiled": "~~主人,水烧开了~~", + "heating": "加热中", + "keepingWarm": "保温中", + "failedAccept": "接受消息失败", + "failedSend": "发送消息失败", + "timedTask":"定时任务", + "logging":"日志记录", + "dailyExecution": "每天 执行", + "input": "请输入...", + "hour": "时", + "minute":"分", + "temperature": "温度", + "cancle":"取消", + "buttonOk": "确定", + "repairservice": "上门维修服务", + "service": "上门维修,贴身服务", + "amount": "¥100", + "serviceTime": "服务时间", + "time": "周三14:00", + "contact": "联系商家", + "buyNow": "立即购买", + "drinkReminder": "喝水提醒", + "save": "保存", + "modeSelect": "模式选择", + "timing": "定时", + "interval": "间隔", + "setTime": "设置时间点", + "edit": "编辑", + "IntervalLength": "间隔时长", + "hours": "h", + "12hours": "12h" + + }, + "files": { + "backSrc": "/common/img/icon_back.png", + "deviceIcon": "/common/img/ID_pic.png", + "successIcon": "/common/img/net_success.png", + "homeBanner": "/common/img/home_banner.png", + "timingTask": "/common/img/home_icon_timing_task.png", + "iconAlarm": "/common/img/icon_alarm_clock.png", + "iconWater": "/common/img/icon_water_clock.png", + "startNotice": "/common/img/start_notice.png", + "waterNotice": "/common/img/water_notice.png", + "iconSrc": "common/img/icon_plus.png", + "serviceBack": "/common/img/BG.png", + "returnImg": "/common/img/icon_back_white.png", + "towardImg":"/common/img/icon_toward.png", + "turnOnImg": "/common/img/water notice _icon_turn.png" + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.css new file mode 100755 index 0000000000000000000000000000000000000000..ca8bd1e4b73b37fc5bfb819b4485f44d5a800e23 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.css @@ -0,0 +1,45 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + + +.w192h192{ + width: 192px; + height: 192px; +} + +.w55h55{ + width: 55px; + height: 55px; +} + +.mbottom10 { + width: 155px; + height: 110px; + margin-bottom: 10px; +} + +.mbottom4 { + width: 200px; + margin-bottom: 4px; + +} +.padding40 { + width: 320px; + height: 120px; + padding: 40px 40px 40px 40px; +} + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..106660505ada2cf491062029a4ba3452bc9435a9 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.hml @@ -0,0 +1,195 @@ + + + + +
+ +
+ + +
+ {{SwitchValue}} +
+ {{TempNumber}}℃ + {{TempState}} +
+ +
+
+ + + {{$t('strings.holdingTemperature')}} +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ {{$t('strings.25temperature')}} +
+
+ {{$t('strings.50temperature')}} +
+
+ {{$t('strings.80temperature')}} +
+
+ {{$t('strings.99temperature')}} +
+
+
+
+ {{$t('strings.warmWater')}} +
+
+ {{$t('strings.milk')}} +
+
+ {{$t('strings.tea')}} +
+
+ {{$t('strings.boilingWater')}} +
+
+ + +
+
+ {{$item.textvalue}} +
+
+
+
+ {{$item.tpvalue}} +
+
+ + +
+ + {{$t('strings.100temperature')}} +
+ {{temp}}℃ + + +
+ {{$t('strings.holdingTime')}} + {{$t('strings.keepWarm')}} + +
+ + +
+ + {{$t('strings.12hours')}} +
+ {{capacity}}h +
+ +
+
+ +
+ {{$t('strings.more')}} +
+ + +
+
+ + +
+ {{$t('strings.autoSet')}} +
+
+ + {{$t('strings.alarmClock')}} + +
+
+
+
+ + {{$t('strings.waterClock')}} + +
+
+ {{$t('strings.ServiceRecommond')}} + +
+ + + +
+
+ +
+ {{$t('strings.setted')}} {{TextMessage}} {{$t('strings.running')}} +
+ + +
+
+
+ + + +
+
+ +
+ {{DrinkTime}} +
+ + +
+
+
+ + + +
+
+ {{$t('strings.setName')}} + +
+
+ {{$t('strings.temperature')}} + + {{temperature}}℃ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.js new file mode 100755 index 0000000000000000000000000000000000000000..2c19ef80a4cb06b9fe48625b236a9a7693da6890 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/device/index.js @@ -0,0 +1,618 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; +import app from '@system.app'; + +var faSoftapUtil = require('fa-softaputil'); +var fan_constants = require("fan-constants"); + +export default { + data: { + + IsFullWindow: false, + MoreVisible: false, + NetState: true, + SuccessFlag: false, + SwitchValue: '', + isSubscribeControlState: false, + + SwitchImg: "/common/img/ic_power_off.png", + SwitchState: 0, + TempNumber: "50", + TempState: '', + + IconCoffee: "/common/img/home_icon_coffee_off.png", + IconMilk: "/common/img/home_icon_milk_off.png", + IconTea: "/common/img/home_icon_tea_off.png", + IconWater: "/common/img/home_icon_water_off.png", + + WarmWaterColor: "#9B9B9B", + MilkColor: "#9B9B9B", + TeaColor: "#9B9B9B", + BoiledWaterColor: "#9B9B9B", + + BoiledColor: "#ff9600", + WarmColor: "#ffffff", + + TextBoiledColor: "#ffffff", + TextWarmColor: "#000000", + + + DefModeValue: [ + { + textvalue: "+", + tpvalue: "", + backcolor:"#9B9B9B" + }, + + { + textvalue: "+", + tpvalue: "", + backcolor:"#9B9B9B" + }, + { + textvalue: "+", + tpvalue: "", + backcolor:"#9B9B9B" + }, + { + textvalue: "+", + tpvalue: "", + backcolor:"#9B9B9B" + }, + ], + + TextMessage: "", + DrinkTime:"", + + state: 1, + temp: 25, + capacity: 8, + type: "", + + name: "boiled", + message: "", + date: "", + hour: "", + minute: "", + + SetName: " ", + temperature: 25, + ShowFlag: 0, + AddIndex: 0, + toast: { + SendFailed: '', + RecvFailed: '', + close: '', + }, + serverIp:'' + }, + + /** + * Get transmission connection sessionid + * Call checkTime once a second + * + */ + onInit() { + this.SwitchValue = this.$t('strings.closed'); + this.TempState = this.$t('strings.keepingWarm'); + + this.toast.RecvFailed = this.$t('strings.failedAccept'); + this.toast.close = this.$t('strings.closed'); + this.toast.SendFailed = this.$t('strings.failedSend'); + + // Successful network ServerIp + this.$app.$def.ServerIp = this.dataInfo; + this.serverIp = this.$app.$def.ServerIp; + + let time = setInterval(()=>{ + this.checkTime() + }, 1000); + }, + + // Show net state + onShow() { + if(this.ShowFlag == 0) { + let timeoutID1 = setTimeout(()=>{ + + this.NetState = false; + this.SuccessFlag = true; + },3000); + + let timeoutID2 = setTimeout(()=> { + + this.NetState = false; + this.SuccessFlag = false; + }, 5000); + this.ShowFlag = 1; + + //Send a message to the device after entering the control page + this.sendControlMessage(); + } + }, + + // Show more components + getMoreClick() { + if (this.IsFullWindow) { + this.IsFullWindow = false; + } else { + this.IsFullWindow = true; + + // Change half mode to full mode + app.requestFullWindow(); + } + }, + + /** + * Timed reminder message detection + * After the time is up, a pop-up reminder + * + */ + checkTime() { + this.date = new Date(); + this.hour = this.date.getHours(); + this.minute = this.date.getMinutes(); + for (let index = 0; index < this.$app.$def.AlarmList.length; index++) { + if (this.$app.$def.AlarmList[index].state == 1) { + if ((this.hour == this.$app.$def.AlarmList[index].hour) && (this.minute == this.$app.$def.AlarmList[index].min)) { + this.addSchedule(); + this.$app.$def.AlarmList[index].state = 0; + this.TextMessage = this.$app.$def.AlarmList[index].message; + this.temp = this.$app.$def.AlarmList[index].temp; + this.type = this.$app.$def.AlarmList[index].message; + this.sendControlMessage(); + } + } + } + for (let index = 0; index < this.$app.$def.MessageList.length; index++) { + if (this.$app.$def.MessageList[index].state == 1) { + if ((this.hour == this.$app.$def.MessageList[index].hour) && (this.minute == this.$app.$def.MessageList[index].min)) { + this.DrinkTime = this.$t('strings.drinkWater'), + this.addScheduleTip(); + this.$app.$def.MessageList[index].state = 0; + } + } + } + for (let index = 0; index < this.$app.$def.IntervalList.length; index++) { + if (this.$app.$def.IntervalList[index].state == 1) { + if ((this.hour == this.$app.$def.IntervalList[index].hour) && (this.minute == this.$app.$def.IntervalList[index].min)) { + this.DrinkTime = this.$t('strings.drinkWater'), + this.addScheduleTip(); + this.$app.$def.IntervalList[index].state = 0; + } + } + } + }, + + /** + * Register message accept callback function + * Receive and process device-side messages + * + */ + onReady: async function onReady() { + this.initSubscribeControlState(); + }, + + // Monitor device response + initSubscribeControlState(){ + if (this.isSubscribeControlState == false){ + let that = this; + faSoftapUtil.FASoftapUtil.subscribe(fan_constants.CONSTANTS.SUBSCRIBE_CONTROL_STATE, function (callbackData) { + var callbackJson = JSON.parse(callbackData); + var event = callbackJson.data; + if (event == "time") { + that.DrinkTime = that.$t('strings.waterBoiled'); + that.addScheduleTip(); + } + else { + var n = event.split(" "); + that.TempNumber = n[0]; + if (n[1].includes("1")) { + that.TempState = that.$t('strings.heating'); + } + else { + that.TempState = that.$t('strings.keepingWarm'); + } + } + that.isSubscribeControlState = true; + }); + } + }, + // Goto service page + gotoFlex() { + router.push({ + uri: 'pages/service/index' + }); + }, + + // Close datedialog. + cancelSchedule() { + this.$element('datedialog').close(); + }, + + // Close datedialog_tip. + cancelScheduleTip() { + this.$element('datedialog_tip').close() + }, + + // Close datedialog_input. + cancelScheduleInput() { + this.$element('datedialog_input').close() + }, + + + // Show datedialog. + addSchedule() { + this.$element('datedialog').show() + }, + + // Show datedialog_tip. + addScheduleTip() { + this.$element('datedialog_tip').show() + }, + + // Show datedialog_input. + addScheduleInput() { + this.$element('datedialog_input').close(); + + this.$app.$def.defModeValue[this.AddIndex].textValue = this.SetName; + this.$app.$def.defModeValue[this.AddIndex].tpValue = this.temperature + "℃"; + this.DefModeValue[this.AddIndex].textvalue = this.$app.$def.defModeValue[this.AddIndex].textValue; + this.DefModeValue[this.AddIndex].tpvalue = this.$app.$def.defModeValue[this.AddIndex].tpValue; + }, + + /** + * select warmWater mode + * + * + */ + warmWater() { + if (this.SwitchState == 1) { + this.temp = 25; + this.type = this.$t('strings.warmWater'); + + this.IconCoffee = "/common/img/home_icon_coffee_selected.png"; + this.IconMilk = "/common/img/home_icon_milk_unselected.png"; + this.IconTea = "/common/img/home_icon_tea_unselected.png"; + this.IconWater = "/common/img/home_icon_water_unselected.png"; + + this.WarmWaterColor = "#487Bfd"; + this.MilkColor = "#000000"; + this.TeaColor = "#000000"; + this.BoiledWaterColor = "#000000"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + + /** + * select milk mode + * + * + */ + milk() { + if (this.SwitchState == 1) { + this.temp = 50; + this.type = this.$t('strings.milk'); + + this.IconCoffee = "/common/img/home_icon_coffee_unselected.png"; + this.IconMilk = "/common/img/home_icon_milk_selected.png"; + this.IconTea = "/common/img/home_icon_tea_unselected.png"; + this.IconWater = "/common/img/home_icon_water_unselected.png"; + + this.WarmWaterColor = "#000000"; + this.MilkColor = "#487Bfd"; + this.TeaColor = "#000000"; + this.BoiledWaterColor = "#000000"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + + /** + * select tea mode + * + * + */ + tea() { + if (this.SwitchState == 1) { + this.temp = 80; + this.type = this.$t('strings.tea'); + + this.IconCoffee = "/common/img/home_icon_coffee_unselected.png"; + this.IconMilk = "/common/img/home_icon_milk_unselected.png"; + this.IconTea = "/common/img/home_icon_tea_selected.png"; + this.IconWater = "/common/img/home_icon_water_unselected.png"; + + this.WarmWaterColor = "#000000"; + this.MilkColor = "#000000"; + this.TeaColor = "#487Bfd"; + this.BoiledWaterColor = "#000000"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + + /** + * select boilingWater mode + * + * + */ + water() { + if (this.SwitchState == 1) { + this.temp = 99; + this.type = this.$t('strings.boilingWater'); + + this.IconCoffee = "/common/img/home_icon_coffee_unselected.png"; + this.IconMilk = "/common/img/home_icon_milk_unselected.png"; + this.IconTea = "/common/img/home_icon_tea_unselected.png"; + this.IconWater = "/common/img/home_icon_water_selected.png"; + + this.WarmWaterColor = "#000000"; + this.MilkColor = "#000000"; + this.TeaColor = "#000000"; + this.BoiledWaterColor = "#487Bfd"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + + /** + * Add custom mode or select this mode + * + * + */ + add(index) { + if (this.SwitchState == 1) { + if (this.DefModeValue[index].textvalue == "+") { + this.AddIndex = index; + this.$element('datedialog_input').show(); + } + else { + this.temp = this.DefModeValue[index].tpvalue.replace("℃",""); + this.type = this.DefModeValue[index].textvalue; + + this.IconCoffee = "/common/img/home_icon_coffee_unselected.png"; + this.IconMilk = "/common/img/home_icon_milk_unselected.png"; + this.IconTea = "/common/img/home_icon_tea_unselected.png"; + this.IconWater = "/common/img/home_icon_water_unselected.png"; + + this.WarmWaterColor = "#000000"; + this.MilkColor = "#000000"; + this.TeaColor = "#000000"; + this.BoiledWaterColor = "#000000"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + this.DefModeValue[index].backcolor="#487Bfd" + + } + } + else { + prompt.showToast({ + message: this.toast.close + }); + } + }, + + /** + * Send boiled messages + * + * + */ + sendMessageBoiled() { + this.BoiledColor = "#ff9600"; + this.WarmColor = "#ffffff"; + this.TextBoiledColor = "#ffffff"; + this.TextWarmColor = "#000000"; + + // Boil down to keep warm + this.name = "boiled"; + this.sendControlMessage(); + }, + + /** + * Send warm messages + * + * + */ + sendMessageWarm() { + this.BoiledColor = "#ffffff"; + this.WarmColor = "#487bfd"; + this.TextBoiledColor = "#000000"; + this.TextWarmColor = "#ffffff"; + + // Heat up to keep warm + this.name = "warm"; + this.sendControlMessage(); + }, + + /** + * Goto timer page + * + * + */ + timerPage() { + router.push({ + uri: 'pages/timer/index' + }); + }, + + /** + * Goto reminder page + * + * + */ + reminderPage() { + router.push({ + uri: 'pages/reminder/index' + }); + }, + + /** + * Set temp + * + * @param e + */ + setTemp(e) { + this.temp = Number(e.progress); + }, + + /** + * Set capacity + * + * @param e + */ + setCapacity(e) { + this.capacity = Number(e.progress); + }, + + /** + * Set SetName + * + * @param e + */ + setName(e) { + this.SetName = e.text; + }, + + /** + * Set temperature + * + * @param e + */ + setTemperature(e) { + this.temperature = Number(e.progress); + }, + + // Call the interface to send protocol messages to the device + sendControlMessage() { + let data = {}; + data.serverIp = this.serverIp; + if (this.state == 0) { + this.message = this.name + " " + this.temp + " " + "0" + " " + this.type; + } + else { + this.message = this.name + " " + this.temp + " " + this.capacity + " " + this.type; + } + data.message = this.message; + faSoftapUtil.FASoftapUtil.sendMessage(data, fan_constants.CONSTANTS.CONTROL_CODE); + }, + + /** + * Auto keep warm switch control fuction + * @param e + * + */ + switchChange(e) { + if (e.checked) { + this.state = 1 + } else { + this.state = 0 + } + }, + + /** + * + * Switch control function and set the page component properties + * + */ + powerChange() { + if (this.SwitchState == 0) { + + this.SwitchImg = "/common/img/ic_power_on.png"; + this.SwitchValue = this.$t('strings.opened'); + this.SwitchState = 1; + + this.IconCoffee = "/common/img/home_icon_coffee_unselected.png"; + this.IconMilk = "/common/img/home_icon_milk_unselected.png"; + this.IconTea = "/common/img/home_icon_tea_unselected.png"; + this.IconWater = "/common/img/home_icon_water_unselected.png"; + + this.WarmWaterColor = "#000000"; + this.MilkColor = "#000000"; + this.TeaColor = "#000000"; + this.BoiledWaterColor = "#000000"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#000000"; + } + + } + else { + + this.SwitchImg = "/common/img/ic_power_off.png" + this.SwitchValue = this.$t('strings.closed'); + this.SwitchState = 0; + + this.IconCoffee = "/common/img/home_icon_coffee_off.png"; + this.IconMilk = "/common/img/home_icon_milk_off.png"; + this.IconTea = "/common/img/home_icon_tea_off.png"; + this.IconWater = "/common/img/home_icon_water_off.png"; + + this.WarmWaterColor = "#9B9B9B"; + this.MilkColor = "#9B9B9B"; + this.TeaColor = "#9B9B9B"; + this.BoiledWaterColor = "#9B9B9B"; + + for(let i =0;i<4;i++) + { + this.DefModeValue[i].backcolor = "#9B9B9B"; + } + + } + }, +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css new file mode 100755 index 0000000000000000000000000000000000000000..9bed503b2a4bdb73457fc841b0900b7e21354c27 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.css @@ -0,0 +1,47 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.solidux{ + width: 720px; + height: 150px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: #cfcfcf; +} + +.mleftright64{ + margin-left:64px ; + margin-right: 64px; +} + +.progressux { + color: #9b9b9b; + margin-top: 52px; + selected-color: #487bfd; + block-color: #487bfd; +} + +.progresstextux { + color: #cfcfcf; + width: 150px; + margin-top: 20px; +} + + + + + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..9764fbbd316e113d73ad52e788432e2e0b12d8d7 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.hml @@ -0,0 +1,56 @@ + + +
+
+ + {{$t('strings.drinkReminder')}} + {{$t('strings.save')}} +
+
+ {{$t('strings.modeSelect')}} +
+ + +
+
+
+
+ {{$item.text}} + {{$item.hour}}:{{$item.min}} + +
+
+ {{$t('strings.IntervalLength')}} + {{capacity}}{{$t('strings.hours')}} +
+
+ + {{$t('strings.12hours')}} +
+
+ +
+
+ + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js new file mode 100755 index 0000000000000000000000000000000000000000..7970b32f98a506947f3d39762e65ec6eea62eb81 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/interval/index.js @@ -0,0 +1,155 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +export default { + data: { + hour: "", + min: "", + capacity: "3", + number: '', + IntervalList: [ + { + text: '', + hour: "09", + min: "00", + buttonsrc: '' + }, + { + text: '', + hour: "20", + min: "00", + buttonsrc: '' + }, + ], + toast:{ + HourMessage:'', + MinMessage:'' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'), + this.toast.MinMessage = this.$t('strings.noMore60'), + + this.IntervalList[0].text = this.$t('strings.startTime'), + this.IntervalList[1].text = this.$t('strings.endTime'), + this.IntervalList[0].buttonsrc = this.$t('files.turnOnImg'), + this.IntervalList[1].buttonsrc = this.$t('files.turnOnImg') + + + + }, + + /** + * Get input hour + * + * @param e + */ + getHour(e) { + if (e.text > 23) { + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = "00"; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e + */ + getMin(e) { + if (e.text > 59) { + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = "00"; + } + this.min = e.text; + }, + + /** + * Push informations into IntervalList object. + * + * @param e + */ + setSchedule() { + let addItem = {}; + if (this.hour < 10) { + this.hour = "0" + this.hour; + } + if (this.min < 10) { + this.min = "0" + this.min; + } + + this.IntervalList[this.number].hour = this.hour; + this.IntervalList[this.number].min = this.min; + + this.$element('datedialog').close() + }, + + // Show dialog. + addSchedule(index) { + this.number = index; + this.$element('datedialog').show() + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close() + }, + + /** + * Get input capacity + * + * @param e + */ + + getCapacity(e) { + this.capacity = Number(e.progress); + }, + + // Back to the previous page. + returnBack(){ + router.back(); + }, + + // Goto reminder page. + reminderPage() { + router.push({ + uri: 'pages/reminder/index' + }); + }, + + // Open send interval reminder switch + changeSwitch() { + let i = (this.IntervalList[1].hour - this.IntervalList[0].hour) / this.capacity; + for (let j = 0; j < i; j++) { + let addItem = + { + hour: this.IntervalList[0] + this.capacity * j, + min: this.IntervalList[1].min - this.IntervalList[0].min, + state: 1, + } + this.$app.$def.IntervalList.push(addItem); + } + router.back(); + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css new file mode 100755 index 0000000000000000000000000000000000000000..34c28e5f95e135a86d432b80c059b7459e8937a3 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.css @@ -0,0 +1,25 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; +.solidux{ + width: 720px; + height: 150px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: #cfcfcf; +} + + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..a65711cd5b3b17202fd806195801fc0451deb78a --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.hml @@ -0,0 +1,49 @@ + + + +
+ +
+ {{$t('strings.modeSelect')}} +
+ + +
+
+
+
+ {{$t('strings.setTime')}} + {{$t('strings.edit')}} +
+
+ {{$item.hour}}:{{$item.min}} + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js new file mode 100755 index 0000000000000000000000000000000000000000..d44b87bf20d62ea0f9352e9e4150860a10122ab5 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/reminder/index.js @@ -0,0 +1,117 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; +export default { + data: { + hour: "", + min: "", + ScheduleList: [], + toast:{ + HourMessage:'', + MinMessage:'' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'), + this.toast.MinMessage = this.$t('strings.noMore60'), + this.ScheduleList = this.$app.$def.MessageList; + }, + + /** + * Get input hour + * + * @param e + */ + getHour(e) { + if (e.text > 23) { + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = "00"; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e + */ + getMin(e) { + if (e.text > 59) { + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = "00"; + } + this.min = e.text; + }, + + /** + * Push informations into MessageList object. + * + * @param e + */ + setSchedule(e) { + if (this.hour < 10) { + this.hour = "0" + this.hour; + } + if (this.min < 10) { + this.min = "0" + this.min; + } + let addItem = + { + hour: this.hour, + min: this.min, + state: 1, + } + this.$app.$def.MessageList.push(addItem); + this.$element('datedialog').close() + }, + + // Show dialog. + addSchedule() { + this.$element('datedialog').show() + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close() + }, + + // Change MessageList object state value. + switchChange(index, e) { + if (e.checked) { + this.$app.$def.MessageList[index].state = 1 + } else { + this.$app.$def.MessageList[index].state = 0 + } + }, + + // Delete one an AlarmList object. + deleteItem(index, e) { + this.$app.$def.MessageList.splice(index, 1); + }, + + // Goto interval page. + intervalPage(){ + router.push({ + uri: 'pages/interval/index' + }); + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.css new file mode 100755 index 0000000000000000000000000000000000000000..bffb56cc4fca310115fe97240b91ffc2d4605ae7 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.css @@ -0,0 +1,46 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; +.center { + width: 100%; + height: 514px; +} + +.imageux{ + width: 55px; + height: 55px; +} + +.between{ + width: 654px; + height: 300px; + justify-content: space-between; + border-radius: 20px; + margin-bottom: 50px; + margin-top: 300px; +} + +.imageux_bottom{ + width: 40px; + height: 40px; + margin-bottom: 32px; +} + +.buttonux{ + width: 360px; + height: 90px; + justify-content: space-around; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..4210e72fecf2ddb79fe6d12cfd712d7342557063 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.hml @@ -0,0 +1,44 @@ + + +
+ +
+
+
+ + {{$t('strings.repairservice')}} +
+
+ {{$t('strings.service')}} + {{$t('strings.amount')}} +
+ {{$t('strings.serviceTime')}} + {{$t('strings.time')}} + +
+
+
+
+ {{$t('strings.contact')}} +
+
+ {{$t('strings.buyNow')}} +
+
+
+ +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.js new file mode 100755 index 0000000000000000000000000000000000000000..c7b295e8149fe758c4d5603f780b0030e2e64d37 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/service/index.js @@ -0,0 +1,30 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +export default { + data: { + }, + + // Goback to device page. + goBack(){ + router.back({ + uri: 'pages/device/index' + }); + }, +} + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css new file mode 100755 index 0000000000000000000000000000000000000000..380536ab676e33181971d7224896086ed75fd128 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.css @@ -0,0 +1,32 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.flexux{ + width: 720px; + height: 250px; + border-radius: 20px; + margin-bottom: 30px; +} + + + + + + + + + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..418118c03c3c35583c3e62b8d2a51a300e53ba10 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.hml @@ -0,0 +1,47 @@ + + + +
+ +
+
+
+ {{$item.message}} +
+ {{$item.hour}}:{{$item.min}} + +
+ {{$t('strings.dailyExecution')}}{{$item.temp}}℃ +
+
+
+ + + +
+
+ + + + +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js new file mode 100755 index 0000000000000000000000000000000000000000..77ef1c8a864960f495b9c9a7c316cc4be3ae8e61 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/control/pages/timer/index.js @@ -0,0 +1,147 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; +export default { + data: { + + message: "", + hour: "", + min: "", + temp: "", + ScheduleList: [], + toast:{ + HourMessage:'', + MinMessage:'', + TempMessage:'' + } + + }, + onInit() { + this.toast.HourMessage = this.$t('strings.noMore24'), + this.toast.MinMessage = this.$t('strings.noMore60'), + this.toast.TempMessage = this.$t('strings.noMore100') + + this.$app.$def.AlarmList[0].message = this.$t('strings.warm'); + this.$app.$def.AlarmList[1].message = this.$t('strings.feeding'); + this.$app.$def.AlarmList[2].message = this.$t('strings.afternoonTea'); + this.$app.$def.AlarmList[3].message = this.$t('strings.gingerTea'); + + this.ScheduleList = this.$app.$def.AlarmList; + }, + + /** + * Get input information + * + * @param e + */ + getMessage(e) { + this.message = e.text; + }, + + /** + * Get input hour + * + * @param e + */ + getHour(e) { + if (e.text > 23) { + prompt.showToast({ + message: this.toast.HourMessage + }); + e.text = "00"; + } + this.hour = e.text; + }, + + /** + * Get input Minute + * + * @param e + */ + getMin(e) { + if (e.text > 59) { + prompt.showToast({ + message: this.toast.MinMessage + }); + e.text = "00"; + } + this.min = e.text; + }, + + /** + * Get input temperature + * + * @param e + */ + getTemp(e) { + if (e.text > 100) { + prompt.showToast({ + message: this.toast.TempMessage + }); + e.text = "100"; + } + this.temp = e.text; + }, + + /** + * Push informations into AlarmList object. + * + * @param e + */ + setSchedule(e) { + if (this.hour < 10) { + this.hour = "0" + this.hour; + } + if (this.min < 10) { + this.min = "0" + this.min; + } + let addItem = + { + message: this.message, + hour: this.hour, + min: this.min, + temp: this.temp, + state: 1, + } + this.$app.$def.AlarmList.push(addItem); + this.$element('datedialog').close() + }, + + // Show dialog. + addSchedule() { + this.$element('datedialog').show() + }, + + // Close dialog. + cancelSchedule() { + this.$element('datedialog').close() + }, + + // Change AlarmList object state value. + switchChange(index, e) { + if (e.checked) { + this.$app.$def.AlarmList[index].state = 1 + } else { + this.$app.$def.AlarmList[index].state = 0 + } + }, + + // Delete one an AlarmList object. + deleteItem(index, e) { + this.$app.$def.AlarmList.splice(index, 1); + }, +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/app.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/app.js new file mode 100755 index 0000000000000000000000000000000000000000..04a20c896a5c2c5fc62364c137f839699509a987 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/app.js @@ -0,0 +1,27 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +var FaSoftapUtil = require('fa-softaputil'); + +export default { + onCreate() { + }, + onDestroy() { + }, + faSoftapUtil: FaSoftapUtil.FASoftapUtil, +}; diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/css/common.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/css/common.css new file mode 100755 index 0000000000000000000000000000000000000000..66a9ca3fa625524c603afc9bdd46f886d617097f --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/css/common.css @@ -0,0 +1,123 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.color_gray{ + color:#a0a0a0; +} + +.color_black{ + color: #000000; +} + +.color_blue { + color: #007dff; +} + +.text_blue{ + text-color:#007dff; +} + +.text_white{ + text-color:#ffffff; +} + +.font32{ + font-size: 32px; +} + +.font25{ + font-size: 25px; +} + +.font35{ + font-size: 35px; +} + +.back_color{ + background-color: #f7f7f7; +} +.back_gray{ + background-color:#f0f0f0; +} + +.back_blue{ + background-color:#007dff; +} + +.flexcol{ + flex-direction: column; +} + +.flexrow{ + flex-direction: row; +} + +.jcenter{ + justify-content: center; +} +.acenter{ + align-items: center; +} +.astart{ + align-items: flex-start; +} +.jstart{ + justify-content: flex-start; +} + +.bradius36{ + border-radius: 36px; +} + +.mbottom20{ + margin-bottom: 20px; +} + +.mbottom40{ + margin-bottom: 40px; +} + +.logoimgsrc { + margin-top: 106px; + width: 187px; + height: 187px; + margin-bottom: 70px; +} + +.imgsrc { + margin-top: 48px; + width: 314px; + height: 314px; + margin-bottom: 44px; +} + +.dividerux { + width: 1px; + height: 100%; + background-color: rgba(0, 0, 0, 0.2); +} +.flexrow_around { + height: 60px; + justify-content: space-around; + align-items: center; + margin-bottom: 32px; + flex-direction: row; +} + +.textux{ + width: 300px; + background-color:transparent; +} + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png new file mode 100755 index 0000000000000000000000000000000000000000..8aace76d60e7983c1ce667bdd8d6e00267f86555 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_about.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png new file mode 100755 index 0000000000000000000000000000000000000000..883cfe9e535ad4ce2383c409994a92b8ad81adde Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_normal.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png new file mode 100755 index 0000000000000000000000000000000000000000..9c97c823f86a661a21c62cec8f29dc1672fd8667 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/ic_wlan.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/icon.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..f488f9adbaa27a1425b8b91b251b89de8c02bc0b Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/icon.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png new file mode 100755 index 0000000000000000000000000000000000000000..440509f0b496026017159847606b4ec096d43d53 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/light_on.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png new file mode 100755 index 0000000000000000000000000000000000000000..99733b2fe98246a4d7b8de2831b616de7a4e5b3c Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/img/right_grey.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css new file mode 100755 index 0000000000000000000000000000000000000000..4d478eba330b20495c9b46d05e71818760e90004 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.css @@ -0,0 +1,21 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../css/common.css'; +.devicenameux{ + color: #000000; + font-size: 40px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml new file mode 100755 index 0000000000000000000000000000000000000000..815de8bb86a53c6c15c1479d9edd5e0147d222aa --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{device_name}} +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js new file mode 100755 index 0000000000000000000000000000000000000000..b827a3fd19acc38a5a28e9bcc372f050f00e9385 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/devicelogo/devicelogo.js @@ -0,0 +1,24 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'logo_img', + 'device_name', + ], + +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css new file mode 100755 index 0000000000000000000000000000000000000000..7ef10c8e3e6f0e6d57a7f5ca7e676dd35750b2f3 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.css @@ -0,0 +1,20 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../css/common.css'; +.titleux{ + font-size: 45px; + margin-bottom: 70px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml new file mode 100755 index 0000000000000000000000000000000000000000..e91edecb696221f47c1b45e99ac55860488ecb16 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.hml @@ -0,0 +1,21 @@ + + +
+
+ + {{title_text}} +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js new file mode 100755 index 0000000000000000000000000000000000000000..3c541cea2b0e84b13773c8f7d8a0a7bf0a0adb47 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/common/pages/logotitle/logotitle.js @@ -0,0 +1,24 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import app from '@system.app'; +import router from '@system.router'; +export default { + props: [ + 'logo_src', + 'title_text', + ], + +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json new file mode 100755 index 0000000000000000000000000000000000000000..75c76dce557494d008f6cabeb30d0ea5d8fd0462 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/en-US.json @@ -0,0 +1,50 @@ +{ + "strings": { + "versionNum": "Version1.0.0", + "deviceName": "SmartKettle", + "authorizeDescription": "YouNeedToAuthorizeAndLogInWithYourMobilePhone", + "login":"HuaweiAccountLogin", + "cancle":"Cancel", + "determine":"YouAgree", + "privacyStatement":"xxxUserAgreementAndPrivacyStatement", + "apply": "Apply", + "getPhoneNum": "GetYourMobileNumber", + "phoneNum": "18112367889", + "setWifi":"SetWiFi", + "authorization": "Authorization", + "tip": "TheDataSharedToXXXIsGovernedByTheThirdPartyPrivacyStatement.YouCanCancelTheAuthorizationInThePrivacyCenterOfHuaweiAccount", + "networkSet":"NetworkSettings", + "otherNet": "UseOtherWirelessNetworks", + "buttonOk": "Determine", + "locationSet": "LocationSetting", + "family":"Family", + "myHouse":"MyHome", + "noSupport": "NotSupport", + "getWifiFailed": "FailedToGetWiFiList", + "findFailed":"DeviceDiscoveryFailed", + "connectFailed":"FailedToConnectDevice", + "configFailed": "DeviceDistributionNetworkFailure", + "livingRoom": "LivingRoom", + "bedroom": "BedRoom", + "secondBedroom": "S'BedRoom", + "restaurant": "Restaurant", + "study": "Study", + "Restroom": "Restroom", + "bathroom": "Bathroom", + "balcony": "Balcony", + "readytoconnectInfo": "PleaseConfirmThatTheDeviceHasBeenReset,ClickSetWiFiAndConnect'Kettle_AP'Hotpot,ClickTheStartDistributionButton", + "readytoconnect": "DistributionNetwork", + "notConnectHotSpot": "NotConnected'Kettle_AP'Hotpot", + "configNetError": "DistributionNetworkFailure", + "connectBackInfo": "PleaseConnectBackToTheHotspot" + + }, + "files": { + "logoImg": "/common/img/icon.png", + "icSrc": "/common/img/ic_normal.png", + "aboutSrc":"/common/img/ic_about.png", + "lightOn":"/common/img/light_on.png", + "logoSrc": "/common/img/icon.png", + "rightSrc":"/common/img/right_grey.png" + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json new file mode 100755 index 0000000000000000000000000000000000000000..08c83da5e5b7592db4f2df1b0befcb803ed1130c --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/i18n/zh-CN.json @@ -0,0 +1,50 @@ +{ + "strings": { + "versionNum": "版本1.0.0", + "deviceName": "智能恒温热水壶", + "authorizeDescription": "继续使用需要授权并用手机号登录", + "login":"华为账号快速登录", + "cancle":"取消", + "determine":"登录表示您同意", + "privacyStatement":"xxx用户协议和隐私声明", + "apply": "申请", + "getPhoneNum": "获取您的手机号码", + "phoneNum": "18112367889", + "authorization": "授权", + "tip": "分享给xxx的数据由第三方隐私声明管辖。您可以随时在华为账号的隐私中心中取消授权", + "networkSet":"网络设置", + "otherNet": "使用其它无线网络", + "buttonOk": "确定", + "locationSet": "位置设置", + "family":"家庭", + "setWifi":"设置wifi", + "myHouse":"我的家", + "noSupport": "不支持", + "getWifiFailed": "获取wifi列表失败", + "findFailed":"发现设备失败", + "connectFailed":"连接设备失败", + "configFailed": "设备配网失败", + "livingRoom": "客厅", + "bedroom": "卧室", + "secondBedroom": "次卧", + "restaurant": "餐厅", + "study": "书房", + "Restroom": "洗手间", + "bathroom": "浴室", + "balcony": "阳台", + "readytoconnectInfo": "请确定设备已经复位后,点击设置wifi 并连接Kettle_AP热点后,再点击开始配网按钮", + "readytoconnect": "开始配网", + "notConnectHotSpot": "尚未连接Kettle_AP热点", + "configNetError": "配网失败", + "connectBackInfo": "请连接回热点" + + }, + "files": { + "logoImg": "/common/img/icon.png", + "icSrc": "/common/img/ic_normal.png", + "aboutSrc":"/common/img/ic_about.png", + "lightOn":"/common/img/light_on.png", + "logoSrc": "/common/img/icon.png", + "rightSrc":"/common/img/right_grey.png" + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css new file mode 100755 index 0000000000000000000000000000000000000000..6ec0a57a8b1dd0309d2d5b1889c75ddd4253e45d --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.css @@ -0,0 +1,27 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.buttonux{ + margin-left: 32px; + width: 90%; + height: 80px; + background-color: transparent; + margin-bottom: 60px; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color:rgba(0, 0, 0, 0.2); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..7153b6af4b4c218e1a35f514ee635bc0c73295c3 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.hml @@ -0,0 +1,39 @@ + + +
+ +
+
+ + +
+
+ + +
+ {{$t('strings.otherNet')}} +
+
+ +
+ +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js new file mode 100755 index 0000000000000000000000000000000000000000..da84c7e1a94a092df7a082d71bfabe7b32f0b4c6 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/confignet/index.js @@ -0,0 +1,85 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + oldWifi:"", + wifiName:"", + wifiPassword:"", + NetworkFlag: false, + text:'' + }, + onInit() { + this.text = this.$t('strings.buttonOk'), + this.wifiName = this.oldWifi; + }, + + // goto locationset page. + goBack() { + router.push({ + uri: "pages/phone/index" + }) + }, + + // Call find Device interface. + goNext() { + let that = this; + this.NetworkFlag = true; + let wifiName = this.wifiName; + + let data = {}; + data.cmd = 0x20; + let param ={}; + param.wifiName = this.wifiName; + param.wifiPassword = this.wifiPassword; + data.param = param; + let toastConfigNetError = this.$t("strings").configNetError; + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.SET_WIFI_CODE).then(function(res){ + let result = JSON.parse(res); + if (result.code == 200) { + // get serverip + let serverIp = ""; + router.push({ + uri: "pages/locationset/index", + params: { + serverIp: result.result.ip, + wifiName: wifiName + } + }) + } else { + prompt.showToast({ + message: toastConfigNetError + result.errmsg + }); + that.NetworkFlag = false; + } + }); + }, + changeWifiName(e){ + this.wifiName = e.value; + }, + changeWifiPassword(e){ + this.wifiPassword = e.value; + }, + useOtherNet(){ + router.push({ + uri: "pages/otherWifi/index", + }) + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.css new file mode 100755 index 0000000000000000000000000000000000000000..a159433fce84990149ed19ce1192d20f3103c3f5 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.css @@ -0,0 +1,22 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.imageux{ + margin-right: 20px; + width: 60px; + height:60px; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..ebc2df64ebc8f15c47badbb60b5d3878142e8cfc --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.hml @@ -0,0 +1,35 @@ + + + +
+
+ + {{$t('strings.versionNum')}} + {{$t('strings.authorizeDescription')}} + +
+ + {{$t('strings.login')}} +
+
+ {{$t('strings.cancle')}} +
+
+ {{$t('strings.determine')}} + {{$t('strings.privacyStatement')}} +
+
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.js new file mode 100755 index 0000000000000000000000000000000000000000..c891ad4cb7dcc0a42a20eddd62a69da75cbd9644 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/index/index.js @@ -0,0 +1,36 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from "@system.router" +import app from '@system.app'; +export default { + data: { + + }, + onInit() { + }, + + // Goto phone page. + goNext() { + router.push({ + uri: "pages/phone/index" + }) + }, + + // Exit the current ability. + goBack() { + app.terminate(); + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css new file mode 100755 index 0000000000000000000000000000000000000000..84d913bd690e93240b67c357e4fe67366fa407ef --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.css @@ -0,0 +1,42 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.rightsrcux{ + width: 15px; + height: 27px; + margin-top: 10px; +} + +.homeux{ + margin-left: 32px; + margin-right: 32px; + justify-content: space-around; + margin-top: 48px; + flex-wrap: wrap; + margin-bottom: 48px; +} + +.homeitemux{ + font-weight: 500; + font-size: 24px; + width:138px; + height: 50px; + margin-top: 20px; + text-color:#000000; + margin-right:2px; + +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..920d5b20953dc657410eb9a15d25b1e08f8fffbe --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.hml @@ -0,0 +1,38 @@ + + + +
+ +
+ {{ $t('strings.family') }} +
+ {{ + $t('strings.myHouse') }} + +
+
+
+
+ +
+
+ +
+ +
+ +
+
diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js new file mode 100755 index 0000000000000000000000000000000000000000..7f1730efe8a25e9119c449fa444bd2d8f563f237 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/locationset/index.js @@ -0,0 +1,92 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router' +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + wifiName: "", + serverIp: "", + DeviceSettings: [{ + name: '', + backcolor: "rgba(0, 175, 255, 0.2)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }, { + name: '', + backcolor: "rgba(0, 0, 0, 0.1)" + }], + }, + onInit() { + this.DeviceSettings[0].name = this.$t('strings.livingRoom'); + this.DeviceSettings[1].name = this.$t('strings.bedroom'); + this.DeviceSettings[2].name = this.$t('strings.secondBedroom'); + this.DeviceSettings[3].name = this.$t('strings.restaurant'); + + this.DeviceSettings[4].name = this.$t('strings.study'); + this.DeviceSettings[5].name = this.$t('strings.Restroom'); + this.DeviceSettings[6].name = this.$t('strings.bathroom'); + this.DeviceSettings[7].name = this.$t('strings.balcony'); + }, + + // Goback to confignet page. + goBack() { + app.terminate(); + }, + + // Config network successfully entered the control page,and pass parameter:sessionId. + goNext() { + console.info("aaaaa:"+ this.serverIp); + let data = {}; + let wifiName = this.wifiName; + let ToastMes= this.$t('strings.connectBackInfo') + wifiName; + let serverIp = this.serverIp; + let faSoftapUtil = this.$app.$def.faSoftapUtil; + + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function(res){ + if (res == wifiName) { + let info = { + serverIp: serverIp + } + faSoftapUtil.callNewFa(info,0); + app.terminate(); + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css new file mode 100755 index 0000000000000000000000000000000000000000..dfa95094914df428f3dde427cae22abe7016035f --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.css @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +@import '../../common/css/common.css'; + +.container { + flex-direction: column; + justify-content: center; + padding-top: 30px; + margin: 0 82px; +} + +.title { + font-size: 42px; +} + +.subtitle { + margin: 20px 0px; + font-size: 24px; + opacity: .8; +} + +.list { +} + +.list-item { + height: 124px; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #000000; + +} + +.list-text-box { + flex-direction: column; + justify-content: center; +} + +.ssid { + font-size: 32px; +} + +.tag { + font-size: 28px; + padding-top: 10px; + opacity: .8; +} + +.right-image { + width: 48px; + height: 48px; +} +.cancel{ + margin-bottom: 50px; +} + + diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..98b88fef543ba4a053b20fc355c077c5482f0d11 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.hml @@ -0,0 +1,36 @@ + + +
+ + 使用其他无线网络 + + + 已为您提供设备支持的WLAN网络 + + + + +
+ {{ $item.ssid }} + {{ $item.security }} +
+ +
+
+
+ +
+ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js new file mode 100755 index 0000000000000000000000000000000000000000..ce59d4fc83a52fbac54c0385fcb114b4b101c15f --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/otherWifi/index.js @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router' +import prompt from '@system.prompt'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + wifiList: [] + }, + onInit() { + console.info("time control init") + }, + onShow() { + this.refreshList(); + }, + cancel() { + router.back(); + }, + clickItem(index) { + if (index == 0) { + router.back(); + } + else{ + router.push({ + uri: 'pages/confignet/index', + params: { + oldWifi: this.wifiList[index].ssid + } + }) + } + }, + refreshList(){ + let data = {}; + let that = this; + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_AVAILABLE_WIFI_CODE).then(function(res){ + let result = JSON.parse(res); + console.info("aaaaa " + res); + if (result.code == 200) { + // get serverip + that.wifiList = result.wifi; + } else { + prompt.showToast({ + message: result.errMsg + }); + } + }); + } +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css new file mode 100755 index 0000000000000000000000000000000000000000..498079758640967b76c0e0685925b54e55853292 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.css @@ -0,0 +1,27 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '../../common/css/common.css'; + +.aboutsrcux{ + margin-left: 10px; + width: 35px; + height: 35px; +} + +.lightonsrcux{ + width: 50px; + height: 50px; +} diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml new file mode 100755 index 0000000000000000000000000000000000000000..60c75c753177d0fc5e97931a3eb263daf5c5de05 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.hml @@ -0,0 +1,31 @@ + + + +
+ +
+ + {{$t('strings.readytoconnectInfo')}} + +
+
+ {{$t('strings.setWifi')}} +
+
+ + +
+
\ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js new file mode 100755 index 0000000000000000000000000000000000000000..e8d001435e4378ba6c1b86e7b4a85fcdd047492e --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/js/default/pages/phone/index.js @@ -0,0 +1,75 @@ +/* +Copyright (c) 2021 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import router from '@system.router'; +import prompt from '@system.prompt'; +import app from '@system.app'; + +var fan_constants = require("fan-constants"); + +export default { + data: { + oldWifi: "" + }, + onInit: async function(){ + let data = {}; + let wifi = await this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE); + if (wifi != fan_constants.CONSTANTS.SMARTFAN_WIFI) { + this.oldWifi = wifi; // Record the wifi name before + } + }, + + /** + * Call isSupportWifiAware interface + * + * @return result.code + */ + onReady: function () { + }, + +// Support wifiware and goto confignet page. + goNext: function () { + let data = {}; + let wifi = this.oldWifi; + let ToastMes = this.$t('strings.notConnectHotSpot'); + this.$app.$def.faSoftapUtil.sendMessage(data, fan_constants.CONSTANTS.GET_CURRENT_WIFI_CODE).then(function (res) { + if (res == fan_constants.CONSTANTS.SMARTFAN_WIFI) { + router.push({ + uri: "pages/confignet/index", + params: { + oldWifi: wifi + } + }) + } else { + prompt.showToast({ + message: ToastMes + }); + } + }); + }, + + // Exit the current ability. + goBack() { + app.terminate(); + }, + async goSetWifi(){ + var action = {}; + action.bundleName = "com.android.settings"; + action.abilityName = "com.android.settings.Settings$WifiSettingsActivity"; + action.flag = 16; //Intent.FLAG_NOT_OHOS_COMPONENT + action.data = {}; + await FeatureAbility.startAbility(action); + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/element/string.json b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..f4c2f1ac10c5868f899d957ee04518df249775bc --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能恒温热水壶" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/media/icon.png b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/media/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..2ad2b5ea004abaee13e71dc96f56891047bae494 Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/base/media/icon.png differ diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/resources/en/element/string.json b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/en/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..12ce65119bf79f01a8b8d96ad709df55209a14ae --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/en/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "SmartKettle" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "public" + }, { + "name": "encrypt", + "value": "encrypt" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/main/resources/zh/element/string.json b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/zh/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..f4c2f1ac10c5868f899d957ee04518df249775bc --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,27 @@ +{ + "string": [ + { + "name": "app_name", + "value": "智能恒温热水壶" + }, + { + "name": "mainability_description", + "value": "JS_Phone_Empty Feature Ability" + }, + { + "name": "controlability_description", + "value": "hap sample empty page" + }, + { + "name": "controlserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "forpublic", + "value": "公开" + }, { + "name": "encrypt", + "value": "加密" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java b/ScenarioDemos/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java new file mode 100755 index 0000000000000000000000000000000000000000..c2e5bf5e34a9da7e5c5ceadcffb6deb2615acb7a --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/ohosTest/java/ohos/samples/smartkettle/ExampleOhosTest.java @@ -0,0 +1,14 @@ +package ohos.samples.smartkettle; + +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + assertEquals("ohos.samples.smartkettle", actualBundleName); + } +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java b/ScenarioDemos/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java new file mode 100755 index 0000000000000000000000000000000000000000..8dd0bc64601de04a58317778c04b382b85fd91b7 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/entry/src/test/java/ohos/samples/smartkettle/ExampleTest.java @@ -0,0 +1,9 @@ +package ohos.samples.smartkettle; + +import org.junit.Test; + +public class ExampleTest { + @Test + public void onStart() { + } +} diff --git a/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_control.png b/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_control.png new file mode 100755 index 0000000000000000000000000000000000000000..771667c6a0dbc9aa761f42027cdb61e962a9af8c Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_control.png differ diff --git a/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_response.PNG b/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_response.PNG new file mode 100755 index 0000000000000000000000000000000000000000..e61206a4e69cdd85d90452cb1ebbe85601b8c22a Binary files /dev/null and b/ScenarioDemos/SmartKettleApp/screenshoot/phone/kettle_response.PNG differ diff --git a/ScenarioDemos/SmartKettleApp/settings.gradle b/ScenarioDemos/SmartKettleApp/settings.gradle new file mode 100755 index 0000000000000000000000000000000000000000..28d595f2fba0d06b2025da200383d15f87c4e9f0 --- /dev/null +++ b/ScenarioDemos/SmartKettleApp/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/ScenarioDemos/SmartKettleDevice/README_zh.md b/ScenarioDemos/SmartKettleDevice/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..c0dba2ec5339d0db9530f515768ce3b102248026 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/README_zh.md @@ -0,0 +1,60 @@ +# 智能恒温热水壶代码介绍 + +### 简介 + +​ 本Sample是基于OpenHarmony轻量级系统,利用内核的实时性和丰富的外设拓展功能,模拟智能热水壶设备跟手机FA通信,实现水壶模式控制、温度上报、模拟定时喝水提醒。 + + + +### 使用说明 + +##### 1. 编译步骤 + +1)拷贝本Sample目录下的common、kettle 文件夹到OpenHarmony 系统源码中的applications/sample/wifi-iot/app目录下。 + +2) 修改applications/sample/wifi-iot/app/BUILD.gn 文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,具体配置如下。 + +``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "kettle", + ] + deps = [ "//applications/sample/wifi-iot/app/common/hals:hals" ] +} + +``` + +3)修改hi3861 内核配置文件 + +​ 打开 device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk 文件 + +​ 将 CONFIG_I2C_SUPPORT is not set这一行, 改为CONFIG_I2C_SUPPORT=y + +​ 将 CONFIG_PWM_SUPPORT is not set这一行, 改为CONFIG_PWM_SUPPORT=y + +4) 代码编译和烧录请参考:[链接](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-connection.md) + +##### 2. 与手机应用联动 + +1)准备一个wifi热点A,密码和热点名称自定义。 + +2)提前在手机上安装好智能热水壶手机端软件,然后在设置应用中连接热点A。 + +3) 打开手机端智能热水壶软件,在热点连接列表中找到Kettle_AP热点并连接,随后点击配网发送热点A相关信息给到热水壶设备端完成配网。 + +4)待配网完成后,可以在手机端自由设置热水壶的工作状态和相应模式。 + + + +### 约束限制 + +硬件:HiSpark Wi-Fi IoT 开发套件(本sample会用到 主控板、OLED拓展板、温度传感器拓展板) + +软件:OpenHarmony 2.0 Canary版本。[链接](https://device.harmonyos.com/cn/docs/start/get-code/sourcecode-acquire-0000001050769927) + +OpenHarmony轻量级开发指导:[链接](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-lite-overview-0000001105598722) + +开发工具下载:[链接 + diff --git a/ScenarioDemos/SmartKettleDevice/common/hals/BUILD.gn b/ScenarioDemos/SmartKettleDevice/common/hals/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..fbd1f3af0b4116443be7893f2c005ab0e30639e8 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/hals/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("hals") { + sources = [ + "src/peripheral_hal.c", + "src/utils_hal.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include", + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/hals/src/peripheral_hal.c b/ScenarioDemos/SmartKettleDevice/common/hals/src/peripheral_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..9b1d8dfefb467909c83131a9ecac2d84288d0ea2 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/hals/src/peripheral_hal.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "peripheral_hal.h" +#include "iot_errno.h" +#include "hi_io.h" +#include "hi_adc.h" +#include "hi_types_base.h" +#include "hi_watchdog.h" +#include "hi_pwm.h" + +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val) +{ + if (id == HAL_WIFI_IOT_IO_NAME_MAX) { + return IOT_FAILURE; + } + return hi_io_set_func((hi_io_name)id, val); +} + +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt) +{ + return hi_adc_read((hi_adc_channel_index)channel, (hi_u16*)data, (hi_adc_equ_model_sel)equModel, + (hi_adc_cur_bais)curBais, (hi_u16)rstCnt); +} + +void HalSetWatchDogEnable(int enable) +{ + if (enable == 0) { + hi_watchdog_disable(); + } else { + hi_watchdog_enable(); + } +} + +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq) +{ + return hi_pwm_start((hi_pwm_port)id, (hi_u16)duty, (hi_u16)freq); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/hals/src/utils_hal.c b/ScenarioDemos/SmartKettleDevice/common/hals/src/utils_hal.c new file mode 100755 index 0000000000000000000000000000000000000000..47e517ab98eb1079eeff7b5fad9d8be8b255ef50 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/hals/src/utils_hal.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos_types.h" +#include "hi_time.h" +#include "hi_types_base.h" +#include "utils_hal.h" + +void hal_udelay(uint32 us) +{ + hi_udelay((hi_u32)us); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/include/common_log.h b/ScenarioDemos/SmartKettleDevice/common/include/common_log.h new file mode 100755 index 0000000000000000000000000000000000000000..2702154ebaca9847a03fd9ff14e1ad30f18ea49b --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/include/common_log.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __COMMON_LOG_H__ +#define __COMMON_LOG_H__ + +#include + +#define LOG_D(fmt, args...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_I(fmt, args...) printf("[INFO][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_E(fmt, args...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) + +#endif // __COMMON_LOG_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/include/network_manager_service.h b/ScenarioDemos/SmartKettleDevice/common/include/network_manager_service.h new file mode 100755 index 0000000000000000000000000000000000000000..2221fe4b67632e5a95e45a2b6e615dfdc35fbd19 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/include/network_manager_service.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_MANAGER_SERVICE_H__ +#define __NETWORK_MANAGER_SERVICE_H__ + +typedef enum { + NET_EVENT_NULL, + NET_EVENT_CONFIG, // Config wifi + NET_EVENT_CONFIG_FAIL, // Config wifi failed + NET_EVENT_CONFIG_SUCC, // Config wifi success + NET_EVENT_CONNECTTING, // connectting wifi + NET_EVENT_CONN_FAILED, // connect wifi failed + NET_EVENT_CONNECTTED, // Wifi connected + NET_EVENT_DISCONNECT, // Wifi disconnected + NET_EVENT_RECV_DATA, // Recv message from FA + + NET_EVENT_TYPE_NBR +}NET_EVENT_TYPE; + +typedef enum { + NET_MODE_IDLE, // the idle mode + NET_MODE_CONFIG, // the netcfg in the AP mode + NET_MODE_STA, // the netcfg int the STA mode + + NET_MODE_NBR +}NET_MODE_TYPE; + +typedef enum { + NET_STA_NULL, + NET_STA_CONFIG, // Config wifi + NET_STA_CONNECTTING, // connectting wifi + NET_STA_CONNECTTED, // Wifi connected + NET_STA_DISCONNECT, // Wifi disconnected + + NET_STA_TYPE_NBR +}NET_STA_TYPE; + +/** + * @brief: the network config service callback + * + * @param event reference {@link NET_EVENT_TYPE} + * @param data The data of the event: NET_EVENT_RECV_DATA or NET_EVENT_SEND_DATA + * @since 1.0 + * @version 1.0 + */ +typedef int (*NetManagerEventCallback)(NET_EVENT_TYPE event, void *data); + +/** + * @brief Register the network config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The callback of netcfg module + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief Set the network mode. + * + * @param mode : the network module, reference {@NET_MODE_TYPE} + * @since 1.0 + * @version 1.0 + */ +void NetManagerSetNetMode(int mode); + +/** + * @brief Send msg to FA. + * + * @param msg : the msg to send + * @since 1.0 + * @version 1.0 + * + * @return 0 -- success, others -- failed + */ +int NetManagerSendMsg(const char *msg); + +/** + * @brief UnRegister the network config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetManagerDeinit(void); + +#endif // __NETWORK_MANAGER_SERVICE_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/include/peripheral_hal.h b/ScenarioDemos/SmartKettleDevice/common/include/peripheral_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..7bc596b0e7dc2d452844deb0d0aeba4b20fc2a62 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/include/peripheral_hal.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERIPHERAL_HAL_H +#define PERIPHERAL_HAL_H + +#include "ohos_types.h" + +/* gpio start */ +typedef enum { + /** GPIO hardware pin 0 */ + HAL_WIFI_IOT_IO_NAME_GPIO_0, + /** GPIO hardware pin 1 */ + HAL_WIFI_IOT_IO_NAME_GPIO_1, + /** GPIO hardware pin 2 */ + HAL_WIFI_IOT_IO_NAME_GPIO_2, + /** GPIO hardware pin 3 */ + HAL_WIFI_IOT_IO_NAME_GPIO_3, + /** GPIO hardware pin 4 */ + HAL_WIFI_IOT_IO_NAME_GPIO_4, + /** GPIO hardware pin 5 */ + HAL_WIFI_IOT_IO_NAME_GPIO_5, + /** GPIO hardware pin 6 */ + HAL_WIFI_IOT_IO_NAME_GPIO_6, + /** GPIO hardware pin 7 */ + HAL_WIFI_IOT_IO_NAME_GPIO_7, + /** GPIO hardware pin 8 */ + HAL_WIFI_IOT_IO_NAME_GPIO_8, + /** GPIO hardware pin 9 */ + HAL_WIFI_IOT_IO_NAME_GPIO_9, + /** GPIO hardware pin 10 */ + HAL_WIFI_IOT_IO_NAME_GPIO_10, + /** GPIO hardware pin 11 */ + HAL_WIFI_IOT_IO_NAME_GPIO_11, + /** GPIO hardware pin 12 */ + HAL_WIFI_IOT_IO_NAME_GPIO_12, + /** GPIO hardware pin 13 */ + HAL_WIFI_IOT_IO_NAME_GPIO_13, + /** GPIO hardware pin 14 */ + HAL_WIFI_IOT_IO_NAME_GPIO_14, + /** Maximum value */ + HAL_WIFI_IOT_IO_NAME_MAX, +} HalWifiIotIoName; + +/** + * @brief set IO function. + * + * @param id -- IO number, reference {@ HalWifiIotIoName}. + * @param val -- the io function value which defined in {@ hi_io.h}. + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val); +/* gpio end */ + + +/* adc start */ + +/** + * @brief Enumerates ADC channel indexes. + * + */ +typedef enum { + /** Channel 0 */ + HAL_WIFI_IOT_ADC_CHANNEL_0, + /** Channel 1 */ + HAL_WIFI_IOT_ADC_CHANNEL_1, + /** Channel 2 */ + HAL_WIFI_IOT_ADC_CHANNEL_2, + /** Channel 3 */ + HAL_WIFI_IOT_ADC_CHANNEL_3, + /** Channel 4 */ + HAL_WIFI_IOT_ADC_CHANNEL_4, + /** Channel 5 */ + HAL_WIFI_IOT_ADC_CHANNEL_5, + /** Channel 6 */ + HAL_WIFI_IOT_ADC_CHANNEL_6, + /** Channel 7 */ + HAL_WIFI_IOT_ADC_CHANNEL_7, + /** Button value */ + HAL_WIFI_IOT_ADC_CHANNEL_BUTT, +} HalWifiIotAdcChannelIndex; + +/** + * @brief Enumerates analog power control modes. + */ +typedef enum { + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_AUTO, + /** Manual control (AVDD = 1.8 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_1P8V, + /** Manual control (AVDD = 3.3 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_3P3V, + /** Button value */ + HAL_WIFI_IOT_ADC_CUR_BAIS_BUTT, +} HalWifiIotAdcCurBais; + +/** + * @brief Enumerates equation models. + */ +typedef enum { + /** One-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_1, + /** Two-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_2, + /** Four-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_4, + /** Eight-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_8, + /** Button value */ + HAL_WIFI_IOT_ADC_EQU_MODEL_BUTT, +} HalWifiIotAdcEquModelSel; + +/** + * @brief Reads a piece of sampled data from a specified ADC channel based on the input parameters. + * + * + * + * @param channel Indicates the ADC channel index. + * @param data Indicates the pointer to the address for storing the read data. + * @param equModel Indicates the equation model. + * @param curBais Indicates the analog power control mode. + * @param rstCnt Indicates the count of the time from reset to conversion start. + * One count is equal to 334 ns. The value must range from 0 to 0xFF0. + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt); +/** adc end ****/ + +/** + * @brief set WatchDog enable or disable. + * + * @param enable -- 1 enable, 0 disable. + * + * @since 1.0 + * @version 1.0 + */ +void HalSetWatchDogEnable(int enable); + +/** + * @brief start the pwm. + * + * @param id Port id of PWM + * @param duty The usefull cycles of PWM + * @param freq The total cycles of PWM + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq); + +#endif // PERIPHERAL_HAL_H \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/include/utils_hal.h b/ScenarioDemos/SmartKettleDevice/common/include/utils_hal.h new file mode 100755 index 0000000000000000000000000000000000000000..a64632197cfdabc66f17f863bc7fae0dce3040e3 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/include/utils_hal.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_HAL_H__ +#define __UTILS_HAL_H__ + +void hal_udelay(uint32 us); + +#endif // __UTILS_HAL_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/BUILD.gn b/ScenarioDemos/SmartKettleDevice/common/netcfg/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..0f1f3827594a59b8440de8d089ea6380ee963f9b --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("netcfg") { + sources = [ + "src/network_config.c", + "src/network_server.c", + "src/network_manager_service.c", + "src/softap.c", + "src/wifi_sta.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/include/defines.h b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/defines.h new file mode 100755 index 0000000000000000000000000000000000000000..7d01442f2b065ac9f79df66301c7c263b32aedff --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/defines.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 +#define AP_NAME "HmosAP" + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#endif /* __DEFINES_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_config.h b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_config.h new file mode 100755 index 0000000000000000000000000000000000000000..07b94be39e018c83259d86034b106b6e1e0d0dc8 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_config.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_CONFIG_H__ +#define __NETWORK_CONFIG_H__ + +#include "network_manager_service.h" + +#define NET_TASK_STACK_SIZE (1024*8) +#define NET_TASK_PRIO 31 + +/** + * @brief start net config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The NetEvent callback. event reference {@NET_EVENT_TYPE} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief stop net config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStop(void); + +/** + * @brief set net config mode + * @param mode -- reference {@NET_MODE_TYPE} + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgSetMode(int mode); + +/** + * @brief start connect the wifi + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStartConnect(const char *ssid, const char *pwd); + +#endif /* __NETWORK_CONFIG_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_server.h b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_server.h new file mode 100755 index 0000000000000000000000000000000000000000..aa719ea56cf1bf3bcf86aba2adad4ff2ebbf5dae --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/network_server.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +#include "network_manager_service.h" + +#define NETSERVER_TASK_STACK_SIZE (1024*4) +#define NETSERVER_TASK_PRIO 33 + + +/** + * @brief start netserver task + * + * @param nEventCallback -- The NetEvent callback, + * when the server recv data, + * it will be called with (@NET_EVENT_RECV_DATA) + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerInit(NetManagerEventCallback nEventCallback); + +/** + * @brief stop netserver task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerDeinit(void); + +/** + * @brief set netserver task resume + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStart(void); + +/** + * @brief set netserver task suspend + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStop(void); + +/** + * @brief check the netserver when suspend or not. + * + * @since 1.0 + * @version 1.0 + * + * @return true -- netserver task is activity, false -- netserver is suspend + */ +bool NetServerIsRun(void); + +/** + * @brief send msg to client + * @param msg -- The message to send + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerSendMsg(const char *msg); + +#endif /* __NETWORK_SERVER_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/include/softap.h b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/softap.h new file mode 100755 index 0000000000000000000000000000000000000000..f27a8760dd5060da5d26c0ddea2eec1fc421d213 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/softap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SOFT_AP_H__ +#define __SOFT_AP_H__ + +/** + * @brief start ap mode. + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int SoftApStart(const char *ap_name); + +/** + * @brief stop ap mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void SoftApStop(void); + +#endif /* __SOFT_AP_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/include/wifi_sta.h b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/wifi_sta.h new file mode 100755 index 0000000000000000000000000000000000000000..824a46a056e1c488079dbc06ab13ebf832b8d1c5 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/include/wifi_sta.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_STA_H__ +#define __WIFI_STA_H__ + +#include "wifi_device.h" + +/** + * @brief wifi state change callback. + * @param state -- wifi state, 0 -- wifi not connect, 1 -- wifi connectted + * + * @since 1.0 + * @version 1.0 + * + */ +typedef void (*WifiChangeEvent)(int state); + +/** + * @brief start sta mode. + * @param WifiChange--wifi state changed callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaStart(WifiChangeEvent WifiChange); + +/** + * @brief start connect wifi. + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaConnect(const char *ssid, const char *pwd); + +/** + * @brief stop sta mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void WifiStaStop(void); + +#endif /* __WIFI_STA_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_config.c b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_config.c new file mode 100755 index 0000000000000000000000000000000000000000..72ae0ad12cdb9dbef80fb0b8564b53b4cde7fe61 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_config.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "softap.h" +#include "wifi_sta.h" + +#include "network_config.h" +#include "network_server.h" +#include "defines.h" + +#define SSID_MAX_LEN 32 +#define PWD_MAX_LEN 32 + +#define NET_PORT 8686 + +#define RETRY_TIMES 5 +#define CONNECT_TIMEOUT 20 + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "wifiName" +#define PWD_KEY "wifiPassword" + +#define CMD_CONFIG 0x20 + +typedef struct { + NET_MODE_TYPE mode; + NET_STA_TYPE status; + bool netRun; + int timeCounts; + + NetManagerEventCallback gEventCall; +} NetManagerInfo; + +static NetManagerInfo g_netManager; +const char *g_apName = NULL; + +#define SET_NET_EVENT(s, e, d) ({ \ + if (g_netManager.gEventCall != NULL) { \ + g_netManager.gEventCall(e, d); \ + } \ + g_netManager.status = s; \ +}) + +static void NetCfgConnectStatus(int s) +{ + if (s == 1 && g_netManager.status != NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_CONNECTTED; + } else if (s == 0) { + if (g_netManager.status == NET_STA_CONNECTTED) { + g_netManager.status = NET_STA_DISCONNECT; + } + g_netManager.mode = NET_MODE_IDLE; + } +} + +#define SHIFT_MASK 0xff +#define SHIFT_8BIT(a) (((a) >> 8) & (SHIFT_MASK)) +#define SHIFT_16BIT(a) (((a) >> 16) & (SHIFT_MASK)) +#define SHIFT_24BIT(a) (((a) >> 24) & (SHIFT_MASK)) + +static void GetIpString(uint32_t ip, char *ipAddr, int size) +{ + if (ipAddr == NULL || size <= 0) { + return; + } + + if (sprintf_s(ipAddr, size, "%d.%d.%d.%d", ip & SHIFT_MASK, SHIFT_8BIT(ip), SHIFT_16BIT(ip), SHIFT_24BIT(ip)) < 0) { + LOG_E("GetIpString failed! \n"); + } + LOG_D("ipAddr : %s \n", ipAddr); +} + +int DeviceGetIp(char *buff, int size) +{ + int ret; + long ip; + struct netif *netif_node = netif_find("wlan0"); + if (netif_node == NULL) { + LOG_E("GetLocalWifiIp netif get fail\r\n"); + return -1; + } + + ip4_addr_t ipAddr; + ip4_addr_t netMask; + ip4_addr_t gateWay; + + ret = netifapi_netif_get_addr(netif_node, &ipAddr, &netMask, &gateWay); + if (ret == 0) { + ip = ip4_addr_get_u32(&ipAddr); + GetIpString(ip, buff, size); + return 0; + } + return -1; +} + +static void SendLocalIp(int sockfd, int code) +{ + char ip[BUF_SHORT_SIZE] = {0}; + + if (code == REQUEST_OK) { + if (DeviceGetIp(ip, sizeof(ip)) < 0) { + LOG_E("get local ip failed! \n"); + return; + } + } + + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, "code", code); + json_pobject obj1, obj2; + + if (code != REQUEST_OK) { + obj1 = add_string_to_object(json, "errmsg", "connect wifi failed!"); + obj1 = add_object_to_object(json, "result"); + } else { + obj1 = add_object_to_object(json, "result"); + obj2 = add_number_to_object(obj1, "cmd", CMD_CONFIG); + obj2 = add_string_to_object(obj1, "ip", (const char *)ip); + } + + char *msg = json_to_string(json); + const char *eof = "\r\n"; + LOG_D("send msg : %s \n", msg); + if (send(sockfd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return; + } + send(sockfd, eof, strlen(eof), 0); + + delete_json_object(json); +} + +static int NetCfgConnect(const char *ssid, const char *pwd, bool wait) +{ + int timecnt = 0; + int retval = 0; + if (WifiStaStart(NetCfgConnectStatus) < 0) { + LOG_E("wifista_start \n"); + return -1; + } + + if (WifiStaConnect((const char *)ssid, (const char *)pwd) < 0) { + LOG_E("hal_wifi_start_connect \n"); + return -1; + } + + if (wait) { + while (g_netManager.status != NET_STA_CONNECTTED) { + usleep(USLEEP_500MS); + if (++timecnt > CONNECT_TIMEOUT) { + retval = -1; + break; + } + } + } + + return retval; +} + +static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl) +{ + json_handle json; + json_pobject sub; + + int cmd; + char *ps = NULL; + char *pw = NULL; + + json = parse_json(psr); + if (json == NULL) { + LOG_E("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + if (cmd != CMD_CONFIG) { + LOG_E("CMD TYPE FAILED! cmd=%d \n", cmd); + return -1; + } + + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + LOG_E("get param obj failed! \n"); + free_json(json); + return -1; + } + ps = get_json_string(sub, VAL_KEY); + if (ps == NULL) { + LOG_E("get ssid failed! \n"); + free_json(json); + return -1; + } + + if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + pw = get_json_string(sub, PWD_KEY); + if (pw != NULL) { + LOG_D("pw=%s\n", pw); + if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + } + + free_json(json); + return 0; +} + +static int NetCfgGetSocketValue(int sockfd) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + struct sockaddr_in addr; + socklen_t len; + int result = -1; + char ssid[SSID_MAX_LEN + 1] = {0}; + char pwd[PWD_MAX_LEN + 1] = {0}; + while (1) { + int readBytes; + len = sizeof(addr); + if (g_netManager.mode != NET_MODE_CONFIG) { + break; + } + if (memset_s(recvbuf, BUF_SHORT_SIZE, 0, BUF_SHORT_SIZE) < 0) { + break; + } + readBytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len); + if (readBytes <= 0) { + LOG_E("socket disconnect! \n"); + break; + } + if (ParseWifiInfo((const char*)recvbuf, ssid, sizeof(ssid), pwd, sizeof(pwd)) == 0) { + result = 0; + break; + } + } + if (result != -1) { + int code = REQUEST_OK; + SET_NET_EVENT(NET_STA_CONNECTTING, NET_EVENT_CONNECTTING, NULL); + if (NetCfgConnect(ssid, pwd, true) < 0) { + code = REQUEST_ERR; + WifiStaStop(); + result = -1; + } + + usleep(USLEEP_2000MS); // wait ip ready + SendLocalIp(sockfd, code); + usleep(USLEEP_1000MS); + if (result != -1) { + NetServerStart(); + usleep(USLEEP_100MS); // wait ip ready + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } else { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONN_FAILED, NULL); + } + } + if (memset_s(pwd, sizeof(pwd), 0x00, sizeof(pwd)) < 0) { + return -1; + } + return result; +} + +static int NetCfgSocket(void) +{ + int sockfd; + struct sockaddr_in servaddr; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + LOG_E("socket error! \n"); + return -1; + } + + memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(NET_PORT); + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + LOG_D("监听%d端口\n", NET_PORT); + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { + LOG_E("bind socket! \n"); + close(sockfd); + return -1; + } + + if (listen(sockfd, 1) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + close(sockfd); + return -1; + } + + while (g_netManager.mode == NET_MODE_CONFIG) { + int newfd, retval; + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length); + LOG_D("new socket connect!\n"); + retval = NetCfgGetSocketValue(newfd); + close(newfd); + + if (retval == 0) { + LOG_D("config network success! \n"); + g_netManager.mode = NET_MODE_STA; + } + } + + close(sockfd); + + return 0; +} + +static void NetCfgStartConfig(void) +{ + SET_NET_EVENT(NET_STA_CONFIG, NET_EVENT_CONFIG, NULL); + WifiStaStop(); + if (SoftApStart(g_apName) < 0) { + LOG_E("start softap failed! \n"); + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + if (NetCfgSocket() < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + SoftApStop(); +} + +static void *NetCfgTask(void *arg) +{ + (void)arg; + int netCfgMode = NET_STA_NULL; + while (g_netManager.netRun) { + if (netCfgMode == g_netManager.mode && netCfgMode != NET_MODE_STA) { + usleep(USLEEP_1000MS); + continue; + } + if (netCfgMode != g_netManager.mode) { + netCfgMode = g_netManager.mode; + } + switch (netCfgMode) { + case NET_MODE_CONFIG: + NetCfgStartConfig(); + break; + default: + break; + } + usleep(USLEEP_1000MS); + } + + return NULL; +} + +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + + if (memset_s(&g_netManager, sizeof(g_netManager), 0x00, sizeof(g_netManager)) < 0) { + LOG_E("memset_s g_netManager \n"); + return -1; + } + + g_netManager.gEventCall = nEventCallback; + g_netManager.netRun = true; + g_netManager.mode = NET_STA_CONFIG; + g_apName = apName; + attr.name = "NetManagerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NET_TASK_STACK_SIZE; + attr.priority = NET_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)NetCfgTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetManagerTask!\n"); + return -1; + } + + return 0; +} + +void NetCfgStop(void) +{ + g_netManager.netRun = false; +} + +void NetCfgSetMode(int mode) +{ + g_netManager.mode = mode; +} + +void NetCfgStartConnect(const char *ssid, const char *pwd) +{ + NetCfgConnect(ssid, pwd, false); +} diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_manager_service.c b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_manager_service.c new file mode 100755 index 0000000000000000000000000000000000000000..1ebcd2c337e92bd80bf0645763e3c84e4dbb76fc --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_manager_service.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "network_server.h" +#include "network_config.h" +#include "defines.h" + +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback) +{ + if (NetServerInit(nEventCallback) < 0) { + LOG_E("NetServerInit \n"); + return -1; + } + + if (NetCfgStart(apName, nEventCallback) < 0) { + LOG_E("NetCfgStart \n"); + NetServerDeinit(); + return -1; + } + + return 0; +} + +void NetManagerUnRegister(void) +{ + NetServerDeinit(); + NetCfgStop(); +} + +void NetManagerSetNetMode(int mode) +{ + NetCfgSetMode(mode); +} + +int NetManagerSendMsg(const char *msg) +{ + return NetServerSendMsg(msg); +} diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_server.c b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_server.c new file mode 100755 index 0000000000000000000000000000000000000000..06503833ed06794bdc2b360f0fe94822c2c62bd8 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/network_server.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "common_log.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "json/jsonutil.h" +#include "network_server.h" +#include "defines.h" + +#define SERVER_PORT 8787 +#define MAX_CONNECT 10 + +typedef struct { + int sockfd[MAX_CONNECT]; + int connAmount; + bool isActive; + bool serRun; + + NetManagerEventCallback g_call; +}NetServerInfo; + +static NetServerInfo g_netServer; + +static int NetServerSend(int fd, const char *msg) +{ + const char *eof = "\r\n"; + if (send(fd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return -1; + } + LOG_D("send msg : %s \n", msg); + send(fd, eof, strlen(eof), 0); + + return 0; +} + +static void SendRequest(int sockfd, int code) +{ + json_pobject obj; + json_pobject json = create_json_object(); + + obj = add_number_to_object(json, "code", code); + if (code == REQUEST_OK) { + obj = add_string_to_object(json, "errmsg", ""); + } else { + obj = add_string_to_object(json, "errmsg", "explain params error!"); + } + + char *msg = json_to_string(json); + NetServerSend(sockfd, msg); + delete_json_object(json); +} + +static bool IsSpecialSocket(const char *msg) +{ + char buf[] = {0xff, 0x55, 0xaa, 0x55, 0x00}; + bool result = true; + if (msg == NULL || strlen(msg) < strlen(buf)) { + return false; + } + + for (int i = 0; i < strlen(buf); i++) { + if (msg[i] != buf[i]) { + result = false; + break; + } + } + + return result; +} + +static int ReadHandle(int *sockfd, fd_set *fdSet) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + int recvbytes; + int fd = *sockfd; + int errcode = -1; + + recvbytes = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0); + if (recvbytes <= 0) { + LOG_D("socket may quit!\n"); + FD_CLR(fd, fdSet); + close(fd); + *sockfd = -1; + g_netServer.connAmount--; + return -1; + } + + if (g_netServer.sockfd[0] == -1 && IsSpecialSocket(recvbuf)) { + *sockfd = -1; + g_netServer.sockfd[0] = fd; + return 0; + } + + LOG_D("recv msg[%d] : %s \n", recvbytes, recvbuf); + if (g_netServer.g_call) { + errcode = g_netServer.g_call(NET_EVENT_RECV_DATA, recvbuf); + } + + if (errcode == -1) { + errcode = REQUEST_ERR; + } else { + errcode = REQUEST_OK; + } + + SendRequest(fd, errcode); + + return 0; +} + +static void CheckNewSocket(int sockFd, fd_set *fdSet, int *maxFd) +{ + int newfd; + struct sockaddr_in client_addr; + socklen_t sin_size = sizeof(client_addr); + if (FD_ISSET(sockFd, fdSet) == 0) { + return; + } + + newfd = accept(sockFd, (struct sockaddr *)&client_addr, &sin_size); + LOG_D("accept:: sock_fd = %d, newfd = %d\n", sockFd, newfd); + if (newfd < 0) { + LOG_E("accept:\n"); + return; + } + + g_netServer.connAmount++; + + if (g_netServer.connAmount < MAX_CONNECT) { + for (int i = 1; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] == -1) { + g_netServer.sockfd[i] = newfd; + break; + } + } + + if (newfd > *maxFd) { + *maxFd = newfd; + } + } else { + LOG_E("max connections arrive, exit\n"); + close(newfd); + } +} + +static void SocketListen(int sock_fd) +{ + fd_set fdset; + int maxsock; + maxsock = sock_fd; + + while (g_netServer.serRun) { + int ret; + struct timeval tv = {2, 0}; + FD_ZERO(&fdset); + FD_SET(sock_fd, &fdset); + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + FD_SET(g_netServer.sockfd[i], &fdset); + } + } + ret = select(maxsock + 1, &fdset, NULL, NULL, &tv); + if (ret <= 0) { + continue; + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1 && FD_ISSET(g_netServer.sockfd[i], &fdset)) { + LOG_D("g_netServer.sockfd[%d] = %d\n", i, g_netServer.sockfd[i]); + ReadHandle(&g_netServer.sockfd[i], &fdset); + continue; + } + } + + CheckNewSocket(sock_fd, &fdset, &maxsock); + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + close(g_netServer.sockfd[i]); + g_netServer.sockfd[i] = -1; + } + } +} + +static void StartServer(void) +{ + struct sockaddr_in serv_addr; + int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) { + LOG_E("socket failed! \n"); + g_netServer.serRun = false; + return; + } + + if (memset_s(&serv_addr, sizeof(serv_addr), 0, sizeof(serv_addr)) < 0) { + LOG_E("memset_s faield! \n"); + close(sockfd); + g_netServer.serRun = false; + return; + } + + serv_addr.sin_family = AF_INET; // 使用IPv4地址 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(SERVER_PORT); // 端口 + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + LOG_E("bind failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + if (listen(sockfd, MAX_CONNECT) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + SocketListen(sockfd); + + LOG_D("SOCKET SERVER QUIT! \n"); + + close(sockfd); +} + +static void *NetServerTask(void *param) +{ + while (g_netServer.isActive) { + if (g_netServer.serRun == false) { + usleep(USLEEP_100MS); + continue; + } + + StartServer(); + } + + return NULL; +} + +int NetServerInit(NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + attr.name = "NetServerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NETSERVER_TASK_STACK_SIZE; + attr.priority = NETSERVER_TASK_PRIO; + + if (memset_s(&g_netServer, sizeof(g_netServer), 0x00, sizeof(g_netServer)) < 0) { + LOG_E("memset_s failed! \n"); + return -1; + } + for (int i = 0; i < MAX_CONNECT; i++) { + g_netServer.sockfd[i] = -1; + } + g_netServer.isActive = true; + g_netServer.g_call = nEventCallback; + if (osThreadNew((osThreadFunc_t)NetServerTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetServerTask!\n"); + g_netServer.isActive = false; + return -1; + } + + return 0; +} + +void NetServerDeinit(void) +{ + g_netServer.serRun = false; + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + shutdown(g_netServer.sockfd[i], SHUT_RDWR); + g_netServer.sockfd[i] = -1; + } + } + + osDelay(DELAY_200MS); + g_netServer.isActive = false; +} + +void NetServerStart(void) +{ + g_netServer.serRun = true; +} + +void NetServerStop(void) +{ + g_netServer.serRun = false; + osDelay(DELAY_200MS); +} + +bool NetServerIsRun(void) +{ + return g_netServer.serRun; +} + +int NetServerSendMsg(const char *msg) +{ + if (g_netServer.serRun == false || g_netServer.sockfd[0] == -1) { + LOG_E("net server is not run! \n"); + return -1; + } + + return NetServerSend(g_netServer.sockfd[0], msg); +} diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/src/softap.c b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/softap.c new file mode 100755 index 0000000000000000000000000000000000000000..6fb27d2a74baf4ba7f6b0bd4dd3750c5196bdad9 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/softap.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "softap.h" +#include "defines.h" + +static void ResetAddr(struct netif *pst_lwip_netif) +{ + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + + IP4_ADDR(&st_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&st_gw, 0, 0, 0, 0); + IP4_ADDR(&st_netmask, 0, 0, 0, 0); + + netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw); +} + +int SoftApStart(const char *ap_name) +{ + HotspotConfig config = {0}; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + char *apName = ap_name; + char ifname[BUF_SHORT_SIZE] = {0}; + int retval; + + if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_ACTIVE \n"); + return -1; + } + if (apName == NULL) { + apName = AP_NAME; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), apName) != 0) { + printf("[sample] strcpy ssid fail.\n"); + return -1; + } + config.securityType = WIFI_SEC_TYPE_OPEN; + retval = SetHotspotConfig((const HotspotConfig *)(&config)); + if (retval != WIFI_SUCCESS) { + LOG_E("SetHotspotConfig \n"); + return -1; + } + + retval = EnableHotspot(); + if (retval != WIFI_SUCCESS) { + LOG_E("EnableHotspot failed! \n"); + return -1; + } + return 0; +} + +void SoftApStop(void) +{ + if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_NOT_ACTIVE \n"); + return; + } + + DisableHotspot(); +} diff --git a/ScenarioDemos/SmartKettleDevice/common/netcfg/src/wifi_sta.c b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/wifi_sta.c new file mode 100755 index 0000000000000000000000000000000000000000..ffb4bc775ca4e9c801e210deef3d73a2e409687c --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/common/netcfg/src/wifi_sta.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_sta.h" +#include "defines.h" + +#define TEST_CONNECT_RETRY_COUNT 5 + +static WifiEvent g_staEventHandler = {0}; +static WifiChangeEvent g_wifiChange = NULL; +static int g_connectRetryCount = 0; + +static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (state == WIFI_STATE_AVALIABLE) { + LOG_I("WiFi: Connected.\n"); + g_connectRetryCount = 0; + } else if (state == WIFI_STATE_NOT_AVALIABLE) { + LOG_I("WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason); + if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) { + g_connectRetryCount++; + return; + } + } + if (g_wifiChange) { + g_wifiChange(state); + } +} + +int WifiStaStart(WifiChangeEvent WifiChange) +{ + WifiErrorCode error; + + g_wifiChange = WifiChange; + + if (IsWifiActive() == WIFI_STA_ACTIVE) { + LOG_E("the wifi has been enabled! \n"); + return 1; + } + + error = EnableWifi(); + if (error != WIFI_SUCCESS) { + LOG_E("EnableWifi failed! \n"); + return -1; + } + + g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler; + error = RegisterWifiEvent(&g_staEventHandler); + if (error != WIFI_SUCCESS) { + LOG_E("RegisterWifiEvent fail, error = %d\n", error); + return -1; + } + + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return -1; + } + + return 0; +} + +int WifiStaConnect(const char *ssid, const char *pwd) +{ + WifiDeviceConfig config = {0}; + int netId = 0; + WifiErrorCode error; + + if (ssid == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), ssid) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + + config.ipType = DHCP; + if (pwd == NULL || strlen(pwd) == 0) { + config.securityType = WIFI_SEC_TYPE_OPEN; + } else { + config.securityType = WIFI_SEC_TYPE_PSK; + if (strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), pwd) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + } + + error = AddDeviceConfig(&config, &netId); + if (error != WIFI_SUCCESS) { + LOG_E("AddDeviceConfig! \n"); + return -1; + } + + error = ConnectTo(netId); + if (error != WIFI_SUCCESS) { + LOG_E("ConnectTo! \n"); + return -1; + } + + return 0; +} + +void WifiStaStop(void) +{ + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return; + } + + DisableWifi(); + UnRegisterWifiEvent(&g_staEventHandler); +} + diff --git a/ScenarioDemos/SmartKettleDevice/kettle/BUILD.gn b/ScenarioDemos/SmartKettleDevice/kettle/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..483f78b0898a2aebdfa101ae5ad8228772784183 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +static_library("kettle") { + sources = [ + "src/kettle_button.c", + "src/kettle_common_init.c", + "src/kettle_heating_sys.c", + "src/kettle_main.c", + "src/kettle_oled.c", + "src/kettle_temp_sensor.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/kettle/include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + ] +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_button.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_button.h new file mode 100755 index 0000000000000000000000000000000000000000..5cc046b48920f8b60941a73123897d866358dad4 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_button.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_BUTTON_H__ +#define __KETTLE_BUTTON_H__ + +typedef enum { + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, +}KEY_CODE; + +typedef struct { + int keycode; + int keyvalue; +}KeyEvent; + +typedef void (*KeyEventCallback)(KeyEvent *event); + +/** + * @brief Setting the param of button gpio. + * + * @since 1.0 + * @version 1.0 + */ +void ButtonInit(void); + +/** + * @brief Register the buttion interrupt. + * + * @param eventCall + * @since 1.0 + * @version 1.0 + */ +void RegButtonIrq(KeyEventCallback eventCall); + +#endif // __KETTLE_BUTTON_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_code_tab.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_code_tab.h new file mode 100755 index 0000000000000000000000000000000000000000..12a63da541dafd9e9dde96a13a7bc0b1d4f402d2 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_code_tab.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_CODE_TAB_H__ +#define __KETTLE_CODE_TAB_H__ + +/* **************************16*16******** */ +const unsigned char F16X16[] = { + 0x10, 0x60, 0x02, 0x8C, 0x00, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x40, 0x7E, 0x42, 0x42, 0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x00, /* "温", 0 */ + 0x10, 0x60, 0x02, 0x8C, 0x00, 0xFE, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x7E, 0x01, 0x44, 0x48, 0x50, 0x7F, 0x40, 0x40, 0x7F, 0x50, 0x48, 0x44, 0x40, 0x00, /* "湿", 1 */ + 0x00, 0x00, 0xFC, 0x24, 0x24, 0x24, 0xFC, 0x25, 0x26, 0x24, 0xFC, 0x24, 0x24, 0x24, 0x04, 0x00, + 0x40, 0x30, 0x8F, 0x80, 0x84, 0x4C, 0x55, 0x25, 0x25, 0x25, 0x55, 0x4C, 0x80, 0x80, 0x80, 0x00, /* "度", 2 */ +}; + +const unsigned char HZ_F16X16[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0x80, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x80, 0x00}, + {0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* "开", 1 */ + { + {0x00, 0x20, 0x20, 0x20, 0xA0, 0x60, 0x00, 0xFF, 0x60, 0x80, 0x40, 0x20, 0x18, 0x00, 0x00, 0x00}, + {0x20, 0x10, 0x08, 0x06, 0x01, 0x40, 0x80, 0x7F, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00} + }, /* "水", 2 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 3 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 4 */ + { + {0x00, 0x02, 0x0C, 0xC0, 0x00, 0xF0, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00}, + {0x02, 0x02, 0x7F, 0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x0F, 0x00, 0x00} + }, /* "冲", 5 */ + { + {0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x04, 0x04, 0xFC, 0x04, 0xC4, 0xB4, 0x8C, 0x80, 0x00, 0x00}, + {0x40, 0x22, 0x15, 0x08, 0x16, 0xA1, 0x60, 0x1C, 0x03, 0x00, 0x40, 0x80, 0x40, 0x3F, 0x00, 0x00} + }, /* "奶", 6 */ + { + {0x00, 0x04, 0x04, 0xF4, 0x94, 0x94, 0x94, 0x9F, 0x94, 0x94, 0x94, 0xF4, 0x04, 0x04, 0x00, 0x00}, + {0x40, 0x40, 0x40, 0x7F, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x7F, 0x40, 0x40, 0x40, 0x00} + }, /* "直", 7 */ + { + {0x40, 0x30, 0x0F, 0x88, 0x28, 0x18, 0x08, 0x40, 0x30, 0x0F, 0xC8, 0x08, 0x28, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x7F, 0x20, 0x10, 0x88, 0x40, 0x30, 0x0E, 0x01, 0x0E, 0x30, 0x40, 0x80, 0x00} + }, /* "饮", 8 */ +}; + +const unsigned char HZ_F16X16_1[][2][16] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, /* " ", 0 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x10, 0xFF, 0x10, 0x10, 0xF0, 0x00, 0xF8, 0x08, 0x08, 0xF8, 0x00, 0x00}, + {0x0F, 0x04, 0x84, 0x4F, 0x30, 0x0F, 0x40, 0x80, 0x7F, 0x00, 0x7F, 0x20, 0x20, 0x7F, 0x00, 0x00} + }, /* "咖", 1 */ + { + {0xFC, 0x04, 0x04, 0xFC, 0x00, 0x08, 0x88, 0x88, 0xFF, 0x00, 0x00, 0xFF, 0x88, 0x88, 0x08, 0x00}, + {0x0F, 0x04, 0x04, 0x0F, 0x00, 0x08, 0x08, 0x08, 0xFF, 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, 0x00} + }, /* "啡", 2 */ + { + {0x04, 0x04, 0x04, 0x84, 0x6F, 0x04, 0x04, 0x04, 0xE4, 0x04, 0x8F, 0x44, 0x24, 0x04, 0x04, 0x00}, + {0x04, 0x02, 0x01, 0xFF, 0x00, 0x10, 0x08, 0x04, 0x3F, 0x41, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00} + }, /* "花", 3 */ + { + {0x40, 0x44, 0x54, 0x54, 0x55, 0x56, 0xD4, 0x7C, 0x54, 0x56, 0x55, 0x54, 0x54, 0x44, 0x40, 0x00}, + {0x02, 0x82, 0x82, 0x9A, 0x56, 0x53, 0x22, 0x22, 0x22, 0x52, 0x4E, 0x42, 0x82, 0x02, 0x02, 0x00} + }, /* "姜", 4 */ + { + {0x04, 0x04, 0x04, 0x04, 0x9F, 0x44, 0x24, 0x94, 0x24, 0x44, 0x9F, 0x04, 0x04, 0x04, 0x04, 0x00}, + {0x02, 0x02, 0x21, 0x13, 0x0A, 0x42, 0x82, 0x7F, 0x02, 0x02, 0x0A, 0x13, 0x21, 0x02, 0x02, 0x00} + }, /* "茶", 5 */ +}; + +/* ***********************************6*8*********************************** */ +const unsigned char F6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // ,1 + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ; + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/* ***************************************8*16*********************************** */ +const unsigned char F8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // !1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // #3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // %5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // &6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // (8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // )9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // *10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // +11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // ,12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // -13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // .14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ; 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +const unsigned char BMP1[] = { + 0x00, 0x03, 0x05, 0x09, 0x11, 0xFF, 0x11, 0x89, 0x05, 0xC3, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0xFF, 0x11, 0xAA, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x38, 0x44, 0x82, 0x92, + 0x92, 0x74, 0x01, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x44, 0xC7, 0x01, 0x7D, + 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, + 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, + 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0x00, 0x00, 0xD8, 0xD8, 0xD8, 0xD8, + 0xD8, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0xE6, 0x66, 0x20, 0x00, 0x06, 0x06, 0x86, 0x06, + 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x86, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, + 0x00, 0x86, 0x86, 0x86, 0x86, 0x86, 0x80, 0x80, 0x86, 0x86, 0x06, 0x86, 0x86, 0xC0, 0xC0, 0x86, + 0x86, 0x86, 0x06, 0x06, 0xD0, 0x30, 0x76, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0xFE, 0x00, 0x01, + 0x02, 0x00, 0xC4, 0x18, 0x20, 0x02, 0x9E, 0x63, 0xB2, 0x0E, 0x00, 0xFF, 0x81, 0x81, 0xFF, 0x00, + 0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x23, 0xEA, 0xAA, 0xBF, 0xAA, + 0xEA, 0x03, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x01, 0x09, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xC1, 0xFF, + 0xFF, 0xC1, 0xC1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0xFC, 0xF3, 0xEF, 0xF3, 0xFC, + 0x80, 0xFF, 0x80, 0xEE, 0xEE, 0xEE, 0xF5, 0xFB, 0xFF, 0x9C, 0xBE, 0xB6, 0xB6, 0x88, 0xFF, 0x00, + /* MP3_UI.bmp */ +}; +#endif // __KETTLE_CODE_TAB_H__ diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_common_init.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_common_init.h new file mode 100755 index 0000000000000000000000000000000000000000..e173692fadcc67a35687938a39331219a27d3fc4 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_common_init.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_COMMON_INIT_H__ +#define __KETTLE_COMMON_INIT_H__ + +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "iot_i2c.h" + +/** + * @brief Init the kettle device. Include the button Oled and heating system. + * + * @since 1.0 + * @version 1.0 + */ +void DeviceInit(void); + +#endif /* __KETTLE_COMMON_INIT_H__ */ diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_heating_sys.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_heating_sys.h new file mode 100755 index 0000000000000000000000000000000000000000..93c506f82b7f924514f846b032fd8cc32d8e2dd4 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_heating_sys.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __KETTLE_HEATING_SYS_H__ +#define __KETTLE_HEATING_SYS_H__ + +typedef enum { + WARM_MODE, // heat the water to the setting temp + BOILED_MODE // heat the water to 100 and then decrease to the setting temp +}HEAT_MODE; + +typedef enum { + HEAT_EVENT_CFG_UPDATE, // the heat sys config has been update + HEAT_EVENT_TEMP_CHANGE, // the temp has been changed + HEAT_EVENT_TIMER_REACH // the setting timer has reached +}HEAT_EVENT_TYPE; + +typedef enum { + STAT_WARMING, + STAT_HEATTING +}HEAT_STATUS; + +typedef struct { + HEAT_EVENT_TYPE eType; + int temp; // current temp + int stat; // current stat, the value reference HEAT_STATUS +}HEAT_EVENT; + +// the config info which set by other process +typedef struct { + unsigned int mode; // work mode + unsigned int temp; // temp to keep + unsigned int times; // keep temp times +} HeatSysCfg; + +/** + * @brief: the heat sys event callback, when the event has been occurrences + * + * @param: event-- reference HEAT_EVENT + * @since 1.0 + * @version 1.0 + */ +typedef int (*HeatEventCallback)(HEAT_EVENT *event); + +/** + * @brief The Heating system Init + * + * @returns 0 success, -1 some error occurrences + * @since 1.0 + * @version 1.0 + */ +int HeatSysInit(void); + +/** + * @brief: register the heat sys + * + * @param callback -- the heat sys event callback + * @return 0 success, -1 some error occurrences, 1--heat sys has been registered + * @since 1.0 + * @version 1.0 + */ +int HeatSysRegister(HeatEventCallback callback); + +/** + * @brief: update the heat sys configs + * + * @param cfg -- heat sys configs, reference HeatSysCfg + * @returns 0 success, -1 some error occurrences + * @since 1.0 + * @version 1.0 + */ +int UpdateHeatSysCfg(HeatSysCfg cfg); + +/** + * @brief Heating system deinit, release the heat sys resource. + * + * @since 1.0 + * @version 1.0 + */ +void HeatSysDeInit(void); + +#endif // __KETTLE_HEATING_SYS_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_main.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_main.h new file mode 100755 index 0000000000000000000000000000000000000000..be53afda1bcfc4250ea9cfa9468366039bc8a558 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_main.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KETTLE_MAIN_H__ +#define __KETTLE_MAIN_H__ + +#include "kettle_common_init.h" + +#define DRINK_WATER 25 +#define MILK 50 +#define GINGER_TEA 60 +#define SCENTED_TEA 70 +#define TEAS 80 +#define COFFEE 85 +#define BOILED_WATER 99 +#define APP_DEMO_KETTLE_SLEEP_TIME_US 1000000 + +#define X_KETTLE_SHOW_TEMP 24 +#define Y_KETTLE_SHOW_TEMP 2 +#define X_KETTLE_SHOW_DISCRITION 32 +#define Y_KETTLE_SHOW_DISCRITION 5 + +#define KETTLE_TASK_STACK_SIZE (1024*4) +#define KETTLE_TASK_PRIO (25) + +#endif // __KETTLE_MAIN_H__ diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_oled.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_oled.h new file mode 100755 index 0000000000000000000000000000000000000000..15e944501bdded8febad6620b2ae001d59a4bff9 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_oled.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __APP_DEMO_OLED_H__ +#define __APP_DEMO_OLED_H__ + +#include "ohos_types.h" + +#define WIFI_IOT_OLED_I2C_IDX_0 0 +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 + +#define I2C_REG_ARRAY_LEN (64) +#define BH_SEND_BUFF (1) +#define OLED_SEND_BUFF_LEN (28) +#define OLED_SEND_BUFF_LEN2 (25) +#define OLED_SEND_BUFF_LEN3 (27) +#define OLED_SEND_BUFF_LEN4 (29) +#define Max_Column (128) +#define OLED_DEMO_TASK_STAK_SIZE (4096) +#define OLED_DEMO_TASK_PRIORITY (25) + +#define OLED_ADDRESS 0x78 +#define OLED_ADDRESS_WRITE_CMD 0x00 +#define OLED_ADDRESS_WRITE_DATA 0x40 + +#define OLED_CLEAN_SCREEN ((uint8)0x00) + +#define SLEEP_20_MS 20000 +#define SLEEP_100_MS 100000 + +#define DELAY_10_MS 1 +#define DELAY_100_MS 10 +#define DELAY_200_MS 20 +#define DELAY_250_MS 25 +#define DELAY_500_MS 50 +/* ssd1306 register cmd */ +#define DISPLAY_OFF 0xAE +#define SET_LOW_COLUMN_ADDRESS 0x00 +#define SET_HIGH_COLUMN_ADDRESS 0x10 +#define SET_START_LINE_ADDRESS 0x40 +#define SET_PAGE_ADDRESS 0xB0 +#define CONTRACT_CONTROL 0x81 +#define FULL_SCREEN 0xFF +#define SET_SEGMENT_REMAP 0xA1 +#define NORMAL 0xA6 +#define SET_MULTIPLEX 0xA8 +#define DUTY 0x3F +#define SCAN_DIRECTION 0xC8 +#define DISPLAY_OFFSET 0xD3 +#define DISPLAY_TYPE 0x00 +#define OSC_DIVISION 0xD5 +#define DIVISION 0x80 +#define COLOR_MODE_OFF 0xD8 +#define COLOR 0x05 +#define PRE_CHARGE_PERIOD 0xD9 +#define PERIOD 0xF1 +#define PIN_CONFIGUARTION 0xDA +#define CONFIGUARTION 0x12 +#define SET_VCOMH 0xDB +#define VCOMH 0x30 +#define SET_CHARGE_PUMP_ENABLE 0x8D +#define PUMP_ENABLE 0x14 +#define TURN_ON_OLED_PANEL 0xAF +#define CMD_LENGTH 27 + +#define OLED_I2C_WRITE_CMD_SEND_LEN 2 + +#define HORIZONTAL_COORDINATE_OF_SLOGANS 2 +#define VERTICAL_COORDINATE_OF_SLOGANS 3 +#define CHAR_SIZE_OF_LANTTICE_8_16 16 +#define HORI_PIXEL_OF_LANTTICE_8_16 8 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16 32 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16 16 + +#define CHAR_SIZE_OF_LANTTICE_HZ_16_16_1 48 +#define HORI_PIXEL_OF_LANTTICE_HZ_16_16_1 16 +#define HORI_PIXEL_OF_LANTTICE_6_8 6 + +#define LIMIT_HORI_PIXEL 120 +#define MAX_LINE_OF_LANTTICE 8 +#define SET_POSITION_OFFSET 4 +#define MAX_OLED_INIT_CYCLE_TIMES 5 + +/** + * @brief Oled Show str + * + * @param x The offset of X axis + * y The offset of Y axis + * chr The str that you want show + * charSize The CharSize (eg: 8*6) + * @since 1.0 + * @version 1.0 + */ +void OledShowStr(uint8 x, uint8 y, const char *chr, uint8 charSize); + +/** + * @brief Oled Init Operations + * + * @since 1.0 + * @version 1.0 + */ +uint32 OledInit(void); // Init OLED PANEL + +#endif // __KETTLE_OLED_H__ diff --git a/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_temp_sensor.h b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_temp_sensor.h new file mode 100755 index 0000000000000000000000000000000000000000..285fb4940660fb6d7141e81a4c1bfa2c63b63151 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/include/kettle_temp_sensor.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __KETTLE_TEMP_SENSOR_H__ +#define __KETTLE_TEMP_SENSOR_H__ + +#define WIFI_IOT_SENSOR_I2C_IDX_0 (0) +#define AHT_SLEEP_20MS (20000) // 20ms +#define AHT_SLEEP_50MS (50000) // 50ms +#define AHT_SLEEP_1S (1000000) // 1s +#define AHT_DELAY_10MS (1) // 10ms +#define AHT_DELAY_40MS (4) // 40ms +#define AHT_DELAY_100MS (10) // 100ms +#define AHT_DEVICE_ADDR (0x38) // device addr +#define AHT_DEVICE_READ_STATUS (0x71) // befor read tem&humi data need to send cmd to comfir the +#define AHT_DEVICE_INIT_CMD (0xBE) // aht init cmd +#define AHT_DEVICE_TEST_CMD (0xAC) // test cmd +#define AHT_DEVICE_PARAM_HIGH_BYTE (0x33) +#define AHT_DEVICE_PARAM_LOW_BYTE (0x00) +#define AHT_DEVICE_PARAM_INIT_HIGH (0x08) +#define AHT_DEVICE_CALIBRATION (0x80) +#define AHT_DEVICE_CALIBRATION_ERR (0x1C) +#define AHT_DEVICE_CALIBRATION_ERR_R (0x18) +#define AHT_TASK_SLEEP_TIME (20000) // thread sleep 20ms + +typedef enum { + AHT_TEMPERATURE = 1, // TEMP + AHT_HUMIDITY = 2, // HUMI +} aht_serson_type; + +/** + * @brief The sensor init operation + * + * @return If success return WIFI_IOT_SUCCESS. else return WIFI_IOT_FAILURE. + * @since 1.0 + * @version 1.0 + */ +int TempSensorInit(void); + +/** + * @brief Get the temp value of sensor. + * + * @return Return the temp value. + * @since 1.0 + * @version 1.0 + */ +uint32 GetSensorTemp(void); + +#endif // __KETTLE_TEMP_SENSOR_H__ \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_button.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_button.c new file mode 100755 index 0000000000000000000000000000000000000000..96cb0913d7f0de1d0712281be7cdd0d97834134e --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_button.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "common_log.h" +#include "kettle_button.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "peripheral_hal.h" + +#define WIFI_IOT_GPIO_IDX_5 5 +#define IOT_IO_FUNC_GPIO_5_GPIO 0 + +typedef struct { + KeyEventCallback mEventCall; + int mButtonID; +}KettleButton; + +static KettleButton g_button; +void ButtonIrqCallback(char *param) +{ + LOG_D("Debug for gpio5_irq_callback\n"); + KettleButton *button = (KettleButton *)param; + if (button != NULL && button->mEventCall != NULL) { + KeyEvent e; + e.keycode = button->mButtonID; + e.keyvalue = 1; + button->mEventCall(&e); + } +} + +void ButtonInit(void) +{ + IoTGpioInit(WIFI_IOT_GPIO_IDX_5); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_GPIO); // Set the gpio5 function + IoTGpioSetDir(WIFI_IOT_GPIO_IDX_5, IOT_GPIO_DIR_IN); // Set gpio dir: in/out +} + +void RegButtonIrq(KeyEventCallback eventCall) +{ + g_button.mEventCall = eventCall; + g_button.mButtonID = KEY_5; + if (IoTGpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, + &ButtonIrqCallback, (char *)(&g_button)) != IOT_SUCCESS) { + LOG_E("Register gpio5 isr failed !\n"); + } +} + diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_common_init.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_common_init.c new file mode 100755 index 0000000000000000000000000000000000000000..7c1b5a09974ed0b332c5bb4e9a814c55f32356c2 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_common_init.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_log.h" +#include "kettle_oled.h" +#include "kettle_button.h" +#include "kettle_common_init.h" +#include "kettle_heating_sys.h" +#include "peripheral_hal.h" + +#define I2C_IDX_BAUDRATE (400000) + +static void I2cBusInit(void) +{ + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_13); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); // Set up the gpio funcion as i2c bus + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_14); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); + IoTI2cInit(WIFI_IOT_OLED_I2C_IDX_0, I2C_IDX_BAUDRATE); // Rate: 400kbps + LOG_I("I2C0 bus init success !\n"); +} + +void DeviceInit(void) +{ + ButtonInit(); + I2cBusInit(); + while (IOT_SUCCESS != OledInit()) { + LOG_E("Connecting oled board falied! Please access oled board !\n"); + usleep(SLEEP_100_MS); // refer from the datasheet of SSD1306 + } + LOG_I("Oled init success !\n"); + while (IOT_SUCCESS != HeatSysInit()) { + LOG_E("TempSensorCheckAndInit falied !\n"); + usleep(SLEEP_100_MS); // Keep the power supply stable + } + LOG_I("Device init success !\n"); +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_heating_sys.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_heating_sys.c new file mode 100755 index 0000000000000000000000000000000000000000..63ec5fdb2bd6dbbeea8dd3424d45c56425c56afb --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_heating_sys.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "ohos_types.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "common_log.h" +#include "kettle_heating_sys.h" +#include "kettle_temp_sensor.h" + +#define HEAT_DEFAULT_TEMP (60) +#define MAX_HEAT_TEMP (100) +#define TICKS_NUMBER (100) // 1 ticks = 10ms +#ifndef SLEEP_200_MS +#define SLEEP_200_MS (200000) +#endif + +#define HEAT_TASK_STAK_SIZE (1024*4) +#define HEAT_TASK_PRIORITY (30) + +#define SET_HEAT_EVENT(type, temp, stat) ({ \ + if ((gHeatInfo != NULL) && (gHeatInfo->gEventHeatCallback)) { \ + HEAT_EVENT e = {type, temp, stat}; \ + gHeatInfo->gEventHeatCallback(&e); \ + } \ +}) + +typedef struct { + HeatSysCfg cfg; + + bool mUpdateFlag; + bool boiling; + + uint8_t heatStat; + uint8_t timerCount; + uint8_t heatTemp; + osTimerId_t g_kettleTimerId; + + HeatEventCallback gEventHeatCallback; +}HeatInfo; + +static void HeatSysEnableHeat(void) +{ + LOG_I("enable heat"); +} + +static void HeatSysDisableHeat(void) +{ + LOG_I("disable heat"); +} + +void TimerCallBack(void *arg) +{ + HeatInfo *gHeatInfo = (HeatInfo *)arg; + + if ((gHeatInfo != NULL) && (gHeatInfo->timerCount > 0)) { + gHeatInfo->timerCount--; + } +} + +static void HeatStartTimer(HeatInfo *gHeatInfo) +{ + if (gHeatInfo == NULL) { + LOG_E("NULL POINT! \n"); + return; + } + gHeatInfo->g_kettleTimerId = osTimerNew(&TimerCallBack, osTimerPeriodic, gHeatInfo, NULL); + osTimerStart(gHeatInfo->g_kettleTimerId, TICKS_NUMBER); +} + +static void HeatDealTimerEvent(HeatInfo *gHeatInfo) +{ + if (gHeatInfo == NULL) { + LOG_E("NULL POINT! \n"); + return; + } + + osTimerStop(gHeatInfo->g_kettleTimerId); + osTimerDelete(gHeatInfo->g_kettleTimerId); + gHeatInfo->g_kettleTimerId = NULL; + SET_HEAT_EVENT(HEAT_EVENT_TIMER_REACH, gHeatInfo->heatTemp, gHeatInfo->heatStat); +} + +static void HeatSysCheckStatus(HeatInfo *gHeatInfo, unsigned int temp, bool boiled) +{ + // when current temp larger then the setted temp, change the heat status to warm + if (temp >= gHeatInfo->cfg.temp) { + if (boiled && gHeatInfo->heatStat != STAT_WARMING) { + HeatSysDisableHeat(); + gHeatInfo->heatStat = STAT_WARMING; + } + } else { // when current temp less then the setted temp, change the heat status to heat + if (gHeatInfo->heatStat != STAT_HEATTING) { + HeatSysEnableHeat(); + gHeatInfo->heatStat = STAT_HEATTING; + } + } +} + +static void *HeatedTask(const char *param) +{ + LOG_D("HeatedTask enter\n"); + HeatInfo *gHeatInfo = (HeatInfo *)param; + if (gHeatInfo == NULL) { + LOG_E("gHeatInfo POINT NULL! \n"); + return NULL; + } + + gHeatInfo->heatTemp = GetSensorTemp(); + HeatSysEnableHeat(); + bool workingFlag = false; + + while (1) { + uint32_t temp = GetSensorTemp(); + + + if (gHeatInfo->cfg.mode == BOILED_MODE) { + if (temp == MAX_HEAT_TEMP && gHeatInfo->boiling == false) { // mark the temp has been boiled + gHeatInfo->boiling = true; + } + HeatSysCheckStatus(gHeatInfo, temp, gHeatInfo->boiling); + } else { + HeatSysCheckStatus(gHeatInfo, temp, true); + } + + // In the warm status, when the warm time has been setted, start the timer! + if (gHeatInfo->heatStat == STAT_WARMING) { + if (gHeatInfo->g_kettleTimerId == NULL && gHeatInfo->cfg.times > 0) { + gHeatInfo->timerCount = (gHeatInfo->cfg.times * 60 * 60); // timecount = times*60*60 + HeatStartTimer(gHeatInfo); + } + } + + // When the heat cfg has been updated, must notify the main process + if (gHeatInfo->mUpdateFlag == TRUE) { + SET_HEAT_EVENT(HEAT_EVENT_CFG_UPDATE, temp, gHeatInfo->heatStat); + workingFlag = true; + gHeatInfo->mUpdateFlag = false; + usleep(SLEEP_200_MS); // Release CPU resources. + continue; + } + + // If heat preservation time is over, notify the main process. + if ((gHeatInfo->g_kettleTimerId != NULL) && (gHeatInfo->timerCount == 0)) { + HeatDealTimerEvent(gHeatInfo); + usleep(SLEEP_200_MS); // Release CPU resources. + continue; + } + + // The temp has been changed, notify the main process + if ((temp != gHeatInfo->heatTemp) && (workingFlag == true)) { + gHeatInfo->heatTemp = temp; + SET_HEAT_EVENT(HEAT_EVENT_TEMP_CHANGE, temp, gHeatInfo->heatStat); + } + + usleep(SLEEP_200_MS); // Release CPU resources. + } + LOG_D("EXIT HeatedTask \n"); + + return NULL; +} + +static HeatInfo *gHeatInfo = NULL; // the heat info struct +static bool g_sensorInited = false; + +int HeatSysInit(void) +{ + if (g_sensorInited) { + LOG_E("the TempSensor has been inited! \n"); + return 1; + } + + if (TempSensorInit() < 0) { + LOG_E("AHT20SensorInit failed! \n"); + return -1; + } + + g_sensorInited = true; + + return 0; +} + +int HeatSysRegister(HeatEventCallback callback) +{ + // check whether the sensor has been inited! + if (g_sensorInited == false) { + LOG_E("TempSensor has not been inited! must be inited TempSensor before HeatSysRegister! \n"); + return -1; + } + + if (gHeatInfo != NULL) { + LOG_E("HeatSys has been Registered! \n"); + return 1; + } + + gHeatInfo = (HeatInfo *)malloc(sizeof(HeatInfo)); + if (gHeatInfo == NULL) { + LOG_E("OOM! \n"); + return -1; + } + memset_s(gHeatInfo, sizeof(HeatInfo), 0x00, sizeof(HeatInfo)); + gHeatInfo->heatTemp = HEAT_DEFAULT_TEMP; + gHeatInfo->gEventHeatCallback = callback; + + osThreadAttr_t attr = {0}; + attr.name = (char*)"heattask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = HEAT_TASK_STAK_SIZE; + attr.priority = HEAT_TASK_PRIORITY; + if (osThreadNew((osThreadFunc_t)HeatedTask, gHeatInfo, &attr) == NULL) { + LOG_E("Failed to create HeatedTask !\n"); + } + + return 0; +} + +int UpdateHeatSysCfg(HeatSysCfg cfg) +{ + if (gHeatInfo == NULL) { + LOG_E("HeatSys has not been inited!!!! \n"); + return -1; + } + + gHeatInfo->mUpdateFlag = true; + memcpy_s(&(gHeatInfo->cfg), sizeof(HeatSysCfg), &cfg, sizeof(HeatSysCfg)); + + return 0; +} + +void HeatSysDeInit(void) +{ + if (gHeatInfo != NULL) { + free(gHeatInfo); + gHeatInfo = NULL; + } + g_sensorInited = false; +} diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_main.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_main.c new file mode 100755 index 0000000000000000000000000000000000000000..5ac81026feae5de74f3d64af3a7fbc9d9d083a19 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_main.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_log.h" +#include "kettle_common_init.h" +#include "kettle_button.h" +#include "kettle_heating_sys.h" +#include "kettle_oled.h" +#include "kettle_main.h" +#include "json/jsonutil.h" + +#include "network_manager_service.h" + +static bool g_buttonFlag = false; + +void KettleShowSettingTemp(uint32 settingTemp, const char *description) +{ + /* If the temperature matches the setting in the macro definition, Chinese characters are displayed. + Otherwise, Decripton is displayed. */ + char str[24]; + LOG_I("kettle setting temp: %d\n", settingTemp); + sprintf_s(str, sizeof(str), "temp : %d", settingTemp); + OledShowStr(X_KETTLE_SHOW_TEMP, Y_KETTLE_SHOW_TEMP, " ", CHAR_SIZE_OF_LANTTICE_8_16); // 清空第2行 + OledShowStr(X_KETTLE_SHOW_TEMP, Y_KETTLE_SHOW_TEMP, str, CHAR_SIZE_OF_LANTTICE_8_16); + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, " ", + CHAR_SIZE_OF_LANTTICE_8_16); // Clear this line + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION + 1, " ", + CHAR_SIZE_OF_LANTTICE_8_16); + switch (settingTemp) { + case DRINK_WATER: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "708", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case MILK: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "506", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case GINGER_TEA: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "405", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case SCENTED_TEA: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "305", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case TEAS: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "304", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + case COFFEE: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "102", CHAR_SIZE_OF_LANTTICE_HZ_16_16_1); + break; + case BOILED_WATER: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, "102", CHAR_SIZE_OF_LANTTICE_HZ_16_16); + break; + default: + OledShowStr(X_KETTLE_SHOW_DISCRITION, Y_KETTLE_SHOW_DISCRITION, description, CHAR_SIZE_OF_LANTTICE_8_16); + break; + } + return; +} + +/** + * This function will dealwith the message that receive from FA. It can divide the message into working mode. + * temp time andr description. eg: warm 50 8 milk. And will show the time and description on the Oled screen. + * then use the interface UpdateHeatSysCfg send the these message to heating system. + */ +void ProcessKettleAppMessage(const char *data) +{ + char *json_data = NULL; + char *data1 = NULL; + char *data2 = NULL; + char *settingMode = NULL; + char *settingTemp = NULL; + char *settingTime = NULL; + char *description = NULL; + HeatSysCfg FASetting = {0}; + json_handle json; + + json = parse_json(data); + json_data = get_json_string(json, "message"); + + settingMode = strtok_s((char *)json_data, " ", &data1); + if (settingMode == NULL) { + LOG_E("Receive the operating mode failed. \n"); + return; + } + + if (strcmp(settingMode, "warm") == 0) { + FASetting.mode = WARM_MODE; + } else if (strcmp(settingMode, "boiled") == 0) { + FASetting.mode = BOILED_MODE; + } else { + LOG_E("The operating mode is incorrent\n"); + return; + } + settingTemp = strtok_s(data1, " ", &data2); + if (settingTemp == NULL) { + LOG_E("Receive the temp failed. \n"); + return; + } + FASetting.temp = (unsigned int)atoi(settingTemp); + + settingTime = strtok_s(data2, " ", &description); + if (settingTime == NULL) { + LOG_E("Receive the time failed. \n"); + return; + } + KettleShowSettingTemp(FASetting.temp, description); + UpdateHeatSysCfg(FASetting); + return; +} + +static int NetCfgEventHandle(NET_EVENT_TYPE event, void *data) +{ + switch (event) { + case NET_EVENT_CONNECTTED: + LOG_D("NET_EVENT_CONNECTTED \n"); + OledShowStr(0, 0, " Connected ", 1); + break; + case NET_EVENT_RECV_DATA: + LOG_D("NET_EVENT_RECV_DATA \n"); + if (data == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + ProcessKettleAppMessage(data); + break; + default: + break; + } + + return 0; +} + +int RecvHeatEventHandle(HEAT_EVENT *event) +{ + char message[24] = {0}; + LOG_I("event->eType: %d, event->temp: %d, event->stat: %d\n", event->eType, event->temp, event->stat); + switch (event->eType) { + case HEAT_EVENT_CFG_UPDATE: + case HEAT_EVENT_TEMP_CHANGE: + sprintf_s(message, sizeof(message), "%d %d", event->temp, event->stat); + break; + case HEAT_EVENT_TIMER_REACH: + sprintf_s(message, sizeof(message), "timer"); // Scheduled end + break; + default: + break; + } + + NetManagerSendMsg(message); + + return 0; +} + +void ButtonEventHandle(KeyEvent *event) +{ + (void)event; // not use, Designed for expand multiple keys + g_buttonFlag = true; +} + +static void DealButtonEvent(void) +{ + char message[24] = {0}; + if (g_buttonFlag == true) { + sprintf_s(message, sizeof(message), "time"); // Simulated drinking time + NetManagerSendMsg(message); + g_buttonFlag = false; + } +} + +static void *MainTask(const char *arg) +{ + (void)arg; + DeviceInit(); + RegButtonIrq(ButtonEventHandle); + LOG_I("RegButton success.\n"); + HeatSysRegister(RecvHeatEventHandle); + LOG_I("HeatSys success.\n"); + + NetManagerRegister("Kettle_AP", NetCfgEventHandle); + LOG_I("NetCfg success.\n"); + while (1) { + DealButtonEvent(); // Deal with the button status. press or not + usleep(APP_DEMO_KETTLE_SLEEP_TIME_US); // Release the cpu resources + } + return NULL; +} + +void KettleDemoEntry(void) +{ + osThreadAttr_t attr; + attr.name = "kettleMainTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = KETTLE_TASK_STACK_SIZE; + attr.priority = KETTLE_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)MainTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetCfgTask!\n"); + } + return; +} + +SYS_RUN(KettleDemoEntry); diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_oled.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_oled.c new file mode 100755 index 0000000000000000000000000000000000000000..68af7fb8489ba3673f4d4f3c470cb63f540919d7 --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_oled.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "iot_errno.h" +#include "iot_i2c.h" +#include "common_log.h" +#include "kettle_oled.h" +#include "kettle_code_tab.h" + + +static uint8 OledInitCmd[CMD_LENGTH] = { + DISPLAY_OFF, // Display off + SET_LOW_COLUMN_ADDRESS, // ---set low column address + SET_HIGH_COLUMN_ADDRESS, // ---set high column address + SET_START_LINE_ADDRESS, // --set start line address + SET_PAGE_ADDRESS, // --set page address + CONTRACT_CONTROL, // contract control + FULL_SCREEN, // --128 + SET_SEGMENT_REMAP, // set segment remap + NORMAL, + SET_MULTIPLEX, // --set multiplex ratio(1 to 64) + DUTY, // --1/32 duty + SCAN_DIRECTION, // Com scan direction + DISPLAY_OFFSET, // -set display offset + DISPLAY_TYPE, + OSC_DIVISION, // set osc division + DIVISION, + COLOR_MODE_OFF, // set area color mode off + COLOR, + PRE_CHARGE_PERIOD, // set Pre-Charge Period + PERIOD, + PIN_CONFIGUARTION, // set com pin configuartion + CONFIGUARTION, + SET_VCOMH, // set Vcomh + VCOMH, + SET_CHARGE_PUMP_ENABLE, // set charge pump enable + PUMP_ENABLE, + TURN_ON_OLED_PANEL // --turn on oled panel +}; + +/* I2C write Byte */ +static uint32 I2cWriteByte(uint8 regAddr, uint8 cmd) +{ + uint32 status = 0; + uint8 userData = cmd; + uint8 sendUserCmd [2] = {0x00, userData}; + uint8 sendUserData [2] = {0x40, userData}; + + // write cmd + if (regAddr == 0x00) { + status = IoTI2cWrite(WIFI_IOT_OLED_I2C_IDX_0, OLED_ADDRESS, sendUserCmd, sizeof(sendUserCmd)); + if (status != IOT_SUCCESS) { + LOG_E("===== Error: SSD1306 OLED Screen I2C write status = 0x%x! =====\r\n", status); + return status; + } + } else if (regAddr == 0x40) { // write data + status = IoTI2cWrite(WIFI_IOT_OLED_I2C_IDX_0, OLED_ADDRESS, sendUserData, sizeof(sendUserData)); + if (status != IOT_SUCCESS) { + LOG_E("===== Error: SSD1306 OLED Screen I2C write status = 0x%x! =====\r\n", status); + return status; + } + } + return IOT_SUCCESS; +} + +static uint32 WriteCmd(uint8 cmd) +{ + // Oled write cmd + if (IOT_SUCCESS != I2cWriteByte(OLED_ADDRESS_WRITE_CMD, cmd)) { + LOG_E("===== Error!!! Write Cmd : write device address cmd failed %d =====\r\n", __LINE__); + return IOT_FAILURE; + } + return IOT_SUCCESS; +} + +static uint32 WriteData(uint8 I2C_Data) +{ + // Oled write data + if (IOT_SUCCESS != I2cWriteByte(OLED_ADDRESS_WRITE_DATA, I2C_Data)) { + LOG_E("===== Error!!! Write Data : write device address failed %d =====\r\n", __LINE__); + return IOT_FAILURE; + } + return IOT_SUCCESS; +} + +void OledSetPosition(uint8 x, uint8 y) +{ + if (IOT_SUCCESS != WriteCmd(0xb0 + y)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(((x&0xf0)>>SET_POSITION_OFFSET) | 0x10)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(x & 0x0f)) { + LOG_E("WriteCmd Error \n"); + return; + } +} + +void OledFillScreen(uint8 fii_data) +{ + for (uint8 m = 0; m < MAX_LINE_OF_LANTTICE; m++) { + if (IOT_SUCCESS != WriteCmd(0xb0 + m)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(0x00)) { + LOG_E("WriteCmd Error \n"); + return; + } + if (IOT_SUCCESS != WriteCmd(0x10)) { + LOG_E("WriteCmd Error \n"); + return; + } + for (uint8 n = 0; n < Max_Column; n++) { + if (IOT_SUCCESS != WriteData(fii_data)) { + LOG_E("WriteData Error \n"); + return; + } + } + } +} + +void OledShowChar(uint8 x, uint8 y, uint8 chr, uint8 charSize) +{ + uint8 i; + uint8 c = chr - ' '; // calc the offset + + if (charSize == CHAR_SIZE_OF_LANTTICE_8_16) { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i ]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_8_16; i++) { + WriteData(F8X16[c*CHAR_SIZE_OF_LANTTICE_8_16 + i + HORI_PIXEL_OF_LANTTICE_8_16]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][0][i]); + } + + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16; i++) { + WriteData(HZ_F16X16[c][1][i]); + } + } else if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + c = chr - '0'; + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][0][i]); + } + OledSetPosition(x, y + 1); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_HZ_16_16_1; i++) { + WriteData(HZ_F16X16_1[c][1][i]); + } + } else { + OledSetPosition(x, y); + for (i = 0; i < HORI_PIXEL_OF_LANTTICE_6_8; i++) { + WriteData(F6X8[c][i]); + } + } +} + +void OledShowStr(uint8 x, uint8 y, const char *chr, uint8 charSize) +{ + uint8 j = 0; + if (chr == NULL) { + return; + } + + while (chr[j] != '\0') { + if (x >= LIMIT_HORI_PIXEL) { + LOG_E("please input the correct x parameter\n"); + return; + } + OledShowChar(x, y, chr[j], charSize); + if (charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16 || charSize == CHAR_SIZE_OF_LANTTICE_HZ_16_16_1) { + x += HORI_PIXEL_OF_LANTTICE_HZ_16_16; + } else { + x += HORI_PIXEL_OF_LANTTICE_8_16; + } + j++; + } +} + +uint32 OledInit(void) +{ + uint32 status; + osDelay(DELAY_100_MS); // 100ms Keep the power supply stable. + for (int i = 0; i < CMD_LENGTH; i++) { + status = WriteCmd(OledInitCmd[i]); + if (status != IOT_SUCCESS) { + LOG_E("Failed to write OledInitCmd: 0x%x \n", OledInitCmd[i]); + return IOT_FAILURE; + } + } + + OledFillScreen(0x00); // The screen off + osDelay(DELAY_10_MS); // 10ms + OledShowStr(HORIZONTAL_COORDINATE_OF_SLOGANS, VERTICAL_COORDINATE_OF_SLOGANS, "OpenHarmony OS", 1); + osDelay(DELAY_500_MS); // The time of keep display + OledShowStr(HORIZONTAL_COORDINATE_OF_SLOGANS, VERTICAL_COORDINATE_OF_SLOGANS, " ", 1); + LOG_I("OledInit succuss\n"); + return IOT_SUCCESS; +} \ No newline at end of file diff --git a/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_temp_sensor.c b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_temp_sensor.c new file mode 100755 index 0000000000000000000000000000000000000000..bf396518f357293f3e4cf14fd075bbbf8796688f --- /dev/null +++ b/ScenarioDemos/SmartKettleDevice/kettle/src/kettle_temp_sensor.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include "ohos_types.h" +#include "iot_errno.h" +#include "common_log.h" +#include "kettle_temp_sensor.h" +#include "kettle_main.h" + +#define AHT_REG_ARRAY_LEN (6) +#define AHT_REG_TEMP_BITS_1 (3) +#define AHT_REG_TEMP_BITS_2 (4) +#define AHT_REG_TEMP_BITS_3 (5) +#define AHT_REG_TEMP_OFFSET (16) +#define AHT_REG_TEMP_OFFSET_1 (8) +#define AHT_OC_ARRAY_LEN (6) +#define AHT_SNED_CMD_LEN (3) +#define SENSOR_TASK_STAK_SIZE (1024*4) +#define SENSOR_TASK_PRIORITY (14) +#define AHT_REG_ARRAY_INIT_LEN (1) +#define AHT_CALCULATION (1048576) +#define DECIMAL 10 +#define NUMBER_OF_DECIMAL_POINTS 3 + +int TempSensorInit(void) +{ + uint32 status; + uint8 recvDataInit[AHT_REG_ARRAY_INIT_LEN] = {0}; + uint8 initSendUserCmd[AHT_SNED_CMD_LEN] = {AHT_DEVICE_INIT_CMD, AHT_DEVICE_PARAM_INIT_HIGH, + AHT_DEVICE_PARAM_LOW_BYTE}; + memset_s(&recvDataInit, sizeof(recvDataInit), 0x0, sizeof(recvDataInit)); + status = IoTI2cRead(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x01, recvDataInit, AHT_REG_ARRAY_INIT_LEN); + if (((recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR) + && (recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR_R)) + || (recvDataInit[0] == AHT_DEVICE_CALIBRATION)) { + status = IoTI2cWrite(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x00, initSendUserCmd, AHT_SNED_CMD_LEN); + usleep(AHT_SLEEP_1S); + return IOT_SUCCESS; + } + return status; +} + +uint32 SensorWrite(uint8 triggerCmd, uint8 highByteCmd, uint8 lowByteCmd) +{ + uint32 status; + uint8 _send_user_cmd[AHT_SNED_CMD_LEN] = {triggerCmd, highByteCmd, lowByteCmd}; + status = IoTI2cWrite(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x00, _send_user_cmd, AHT_SNED_CMD_LEN); + + return status; +} + +uint32 SensorRead(uint8 type) +{ + uint8 recvData[AHT_REG_ARRAY_LEN] = {0}; + float temper = 0; + uint32 temper_t = 0; + + memset_s(&recvData, sizeof(recvData), 0x0, sizeof(recvData)); + IoTI2cRead(WIFI_IOT_SENSOR_I2C_IDX_0, (AHT_DEVICE_ADDR<<1) | 0x01, recvData, AHT_REG_ARRAY_LEN); + if (type == AHT_TEMPERATURE) { + temper = (float)((recvData[AHT_REG_TEMP_BITS_1] &0x0f)< { + Intent intent1 = new Intent(); + DeviceSelectDialog dialog = new DeviceSelectDialog(getContext()); + + dialog.setListener(deviceInfo -> { + Intent myIntent = new Intent(); + Operation op = new Intent.OperationBuilder() + .withDeviceId(deviceInfo.getDeviceId()) + .withBundleName(getBundleName()) + .withAbilityName("ohos.samples.tictactoegame.MainAbility") + .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) + .build(); + myIntent.setOperation(op); + myIntent.setParam("data", GAME_COM_IS_SLAVE); + startAbility(myIntent); + + intent1.setParam("user", "main"); + dialog.hide(); + present(new StartAbilitySlice(), intent1); + }); + dialog.show(); + }); + + Text imgGameRule = (Text) findComponentById(ResourceTable.Id_game_rule); + imgGameRule.setClickedListener(component -> { + GameRulesUtils gameRuleDialog = new GameRulesUtils(getContext()); + gameRuleDialog.show(); + }); + } + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } +} + + + diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/slice/StartAbilitySlice.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/slice/StartAbilitySlice.java new file mode 100755 index 0000000000000000000000000000000000000000..b2f664b67ceb8d1f79dfba61a78f53bd72882896 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/slice/StartAbilitySlice.java @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.slice; + +import com.daimajia.ohosanimations.library.Techniques; +import com.daimajia.ohosanimations.library.YoYo; +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.ability.IAbilityConnection; +import ohos.aafwk.content.Intent; +import ohos.aafwk.content.IntentParams; +import ohos.aafwk.content.Operation; +import ohos.agp.components.Image; +import ohos.agp.components.RoundProgressBar; +import ohos.app.dispatcher.TaskDispatcher; +import ohos.bundle.ElementName; +import ohos.eventhandler.EventHandler; +import ohos.eventhandler.EventRunner; +import ohos.eventhandler.InnerEvent; +import ohos.rpc.IRemoteObject; +import ohos.samples.tictactoegame.ResourceTable; +import ohos.samples.tictactoegame.connections.MyRemoteProxy; +import ohos.samples.tictactoegame.utils.DeviceUtils; +import ohos.samples.tictactoegame.utils.GameStatusUtils; +import ohos.samples.tictactoegame.utils.PkUtils; +import ohos.samples.tictactoegame.utils.UIUtils; + +import java.util.Timer; +import java.util.TimerTask; + +public class StartAbilitySlice extends AbilitySlice { + private static final int NOT_USE = 0; + private static final int USE = 1; + private static final int STATSUS_OFF = 0; + private static final int STATSUS_ON = 1; + private static final int IS_HOST = 1; + private static final int IS_ADV = 2; + private static final int IS_STOP = 3; + private static final int COL_NUM = 3; + private static final int ROW_NUM = 3; + private static final int GAME_LOSE = 0; + private static final int GAME_WIN = 1; + private static final int GAME_DOGFALL = 2; + + private static boolean btnRefreshFlag; + private static boolean btnBackFlag; + private int pageStatus = STATSUS_OFF; + private static int gameStatus = STATSUS_OFF; + private static int playGame; + + private static final int GAME_COM_CLICK1 = 101; + private static final int GAME_COM_CLICK9 = 109; + private static final int GAME_COM_GAME_START = 110; + + private static final int GAME_DEFAULT_VALUE = 0; + private static final int GAME_COM_IS_SLAVE = 301; + private static final int GAME_COM_LOST = 401; + private static final int GAME_COM_WIN = 402; + private static final int GAME_COM_DOGFALL = 403; + private static final int GAME_COM_EXIT = 404; + private static final int GAME_COM_RESTART = 501; + + private final static int[][] host = {{NOT_USE, NOT_USE, NOT_USE}, {NOT_USE, NOT_USE, NOT_USE}, {NOT_USE, NOT_USE, NOT_USE}}; + private final static int[][] adversary = {{NOT_USE, NOT_USE, NOT_USE}, {NOT_USE, NOT_USE, NOT_USE}, {NOT_USE, NOT_USE, NOT_USE}}; + private static Image image1; + private static Image image2; + private static Image image3; + private static Image image4; + private static Image image5; + private static Image image6; + private static Image image7; + private static Image image8; + private static Image image9; + + private static Image imageBack; + private static Image imageRefresh; + private static Image imageMe; + private static Image imageDv; + + private static int myImg; + private static int advImg; + private static int resetImg; + public static MyRemoteProxy myProxy = null; + + private static boolean countDownSwitch; + private static Timer timer = null; + public static int midTime; + public static TaskDispatcher myTaskDis; + static RoundProgressBar roPrbar; + + private final IAbilityConnection conn = new IAbilityConnection() { + @Override + public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) { + myProxy = new MyRemoteProxy(iRemoteObject); + } + @Override + public void onAbilityDisconnectDone(ElementName elementName, int i) { + } + }; + + private void ButtonClick(Image imageButton, int idx) { + int row = idx / ROW_NUM; + int column = idx % COL_NUM; + + if ( (gameStatus == STATSUS_ON) && (playGame == IS_HOST) && (myProxy != null) + && (host[row][column] == NOT_USE) && (adversary[row][column] == NOT_USE)) { + host[row][column] = USE; + myProxy.sendCmd(GAME_COM_CLICK1 + idx); + imgUiGenOpe(); + imageButton.setPixelMap(myImg); + } + } + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_ability_start); + + int recParam = intent.getIntParam("data",GAME_DEFAULT_VALUE); + + myTaskDis = getUITaskDispatcher(); + resetImg = ResourceTable.Media_littleBK; + PkUtils.showTip(StartAbilitySlice.this); + + preInit(); + imageMe = (Image) findComponentById(ResourceTable.Id_img_me); + imageDv = (Image) findComponentById(ResourceTable.Id_img_dv); + if (recParam == GAME_COM_IS_SLAVE) { + imageMe.setPixelMap(ResourceTable.Media_user_fork_me); + imageDv.setPixelMap(ResourceTable.Media_user_circled_huawei); + if (pageStatus == STATSUS_OFF){ + pageStatus = STATSUS_ON; + gameStatus = STATSUS_ON; + + myImg = ResourceTable.Media_fork; + advImg = ResourceTable.Media_circled; + playGame = IS_ADV; + } + } else { + imageMe.setPixelMap(ResourceTable.Media_user_circled_me); + imageDv.setPixelMap(ResourceTable.Media_user_fork_huawei); + String recParamUser = intent.getStringParam("user"); + if (recParamUser != null) { + pageStatus = STATSUS_ON; + gameStatus = STATSUS_ON; + myImg = ResourceTable.Media_circled; + advImg = ResourceTable.Media_fork; + playGame = IS_HOST; + + countDownSwitch = true; + midTime = 10; + gameTimer(); + } + } + initView(); + initListener(); + resetImg(); + } + + public void initView() { + String deviceId = DeviceUtils.getDeviceId(); + if (deviceId != null) { + Intent connectPAIntent = new Intent(); + Operation op1 = new Intent.OperationBuilder() + .withDeviceId(deviceId) + .withBundleName(getBundleName()) + .withAbilityName("ohos.samples.tictactoegame.RemoteServiceAbility") + .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) + .build(); + connectPAIntent.setOperation(op1); + connectAbility(connectPAIntent, conn); + } + + imageBack = (Image) findComponentById(ResourceTable.Id_img_back); + imageBack.setPixelMap(ResourceTable.Media_icon_back_dont_set); + imageBack.setClickedListener(componet -> { + if (btnBackFlag) { + btnRefreshFlag = false; + countDownSwitch = false; + Intent intent1 = new Intent(); + present(new MainAbilitySlice(),intent1); + } + }); + imageRefresh = (Image) findComponentById(ResourceTable.Id_img_refresh); + imageRefresh.setPixelMap(ResourceTable.Media_icon_refresh_dont_set); + imageRefresh.setClickedListener(component -> { + if (btnRefreshFlag) { + reSetStart(); + myProxy.sendCmd(GAME_COM_RESTART); + PkUtils.showTip(StartAbilitySlice.this); + playGame = IS_HOST; + btnRefreshFlag = false; + countDownSwitch = true; + midTime = 10; + gameTimer(); + } + }); + } + public void initListener() { + image1 = (Image) findComponentById(ResourceTable.Id_img1); + image1.setClickedListener(componet ->ButtonClick(image1, 0)); + + image2 = (Image) findComponentById(ResourceTable.Id_img2); + image2.setClickedListener(componet ->ButtonClick(image2, 1)); + + image3 = (Image) findComponentById(ResourceTable.Id_img3); + image3.setClickedListener(componet ->ButtonClick(image3, 2)); + + image4 = (Image) findComponentById(ResourceTable.Id_img4); + image4.setClickedListener(componet ->ButtonClick(image4, 3)); + + image5 = (Image) findComponentById(ResourceTable.Id_img5); + image5.setClickedListener(componet ->ButtonClick(image5, 4)); + + image6 = (Image) findComponentById(ResourceTable.Id_img6); + image6.setClickedListener(componet ->ButtonClick(image6, 5)); + + image7 = (Image) findComponentById(ResourceTable.Id_img7); + image7.setClickedListener(componet ->ButtonClick(image7, 6)); + + image8 = (Image) findComponentById(ResourceTable.Id_img8); + image8.setClickedListener(componet ->ButtonClick(image8, 7)); + + image9 = (Image) findComponentById(ResourceTable.Id_img9); + image9.setClickedListener(componet ->ButtonClick(image9, 8)); + } + public static void runImg(Image useImage){ + YoYo.with(Techniques.Swing) + .duration(1000) + .delay(500) + .playOn(useImage); + } + + public void preInit() { + btnBackFlag = false; + btnRefreshFlag = false; + countDownSwitch = false; + timer = null; + + pageStatus = STATSUS_OFF; + gameStatus = STATSUS_OFF; + for(int row = 0; row < ROW_NUM; row++) { + for (int col = 0; col = GAME_COM_CLICK1 && event.eventId <= GAME_COM_CLICK9) { + dealButtonClick(event.eventId - GAME_COM_CLICK1); + return; + } + + switch (event.eventId) { + case GAME_COM_GAME_START: + gameStatus = STATSUS_ON; + break; + case GAME_COM_RESTART: + if (btnBackFlag) { + reSetStart(); + PkUtils.showTip(StartAbilitySlice.image1.getContext()); + } + imageBack.setPixelMap(ResourceTable.Media_icon_back_dont_set); + playGame = IS_ADV; + break; + case GAME_COM_LOST: + GameStatusUtils.showFaild(StartAbilitySlice.image1.getContext()); + btnRefreshFlag = true; + imageRefresh.setPixelMap(ResourceTable.Media_icon_refresh); + btnBackFlag = true; + imageBack.setPixelMap(ResourceTable.Media_icon_back); + gameOver(); + break; + case GAME_COM_WIN: + GameStatusUtils.showWin(StartAbilitySlice.image1.getContext()); + btnBackFlag = true; + imageBack.setPixelMap(ResourceTable.Media_icon_back); + gameOver(); + break; + case GAME_COM_EXIT: + countDownSwitch = true; + break; + case GAME_COM_DOGFALL: + btnRefreshFlag = true; + imageRefresh.setPixelMap(ResourceTable.Media_icon_refresh); + btnBackFlag = true; + imageBack.setPixelMap(ResourceTable.Media_icon_back); + GameStatusUtils.showTie(StartAbilitySlice.image1.getContext()); + gameOver(); + break; + default: + } + } + }; + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } + public static EventHandler getHandler() { + return mmHandler; + } + + public boolean onSaveData(IntentParams intentParams) { + UIUtils.showTip(StartAbilitySlice.this, "onSaveData"); + intentParams.setParam("data","remote"); + return true; + } + + public boolean onRestoreData(IntentParams intentParams) { + UIUtils.showTip(StartAbilitySlice.this, "onRestoreData"); + String data = intentParams.getParam("data").toString(); + UIUtils.showTip(this, data); + return true; + } + + private static void resetImg() { + image1.setPixelMap(resetImg); + image2.setPixelMap(resetImg); + image3.setPixelMap(resetImg); + image4.setPixelMap(resetImg); + image5.setPixelMap(resetImg); + image6.setPixelMap(resetImg); + image7.setPixelMap(resetImg); + image8.setPixelMap(resetImg); + image9.setPixelMap(resetImg); + } + + private static void reSetStart() { + btnBackFlag = false; + resetImg(); + cleanCheckerboard(host); + cleanCheckerboard(adversary); + imageRefresh.setPixelMap(ResourceTable.Media_icon_refresh_dont_set); + imageBack.setPixelMap(ResourceTable.Media_icon_back_dont_set); + gameStatus = STATSUS_ON; + } + + private int drudge() { + for (int i = 0; i < 3; i++) { + if (host[i][0] == USE && host[i][1] == USE && host[i][2] == USE) { + return GAME_WIN; + } + } + for (int i = 0; i < 3; i++) { + if (host[0][i] == USE && host[1][i] == USE && host[2][i] == USE) { + return GAME_WIN; + } + } + if (host[0][0] == USE && host[1][1] == USE && host[2][2] == USE) { + return GAME_WIN; + } + if (host[0][2] == USE && host[1][1] == USE && host[2][0] == USE) { + return GAME_WIN; + } + int useCount = 0; + for (int horl = 0; horl < 3; horl++) { + for (int verl = 0; verl < 3; verl++) { + if (host[horl][verl] == USE) { + useCount++; + } + } + } + if (useCount > 4) { + return GAME_DOGFALL; + } else { + return GAME_LOSE; + } + } + + private static void cleanCheckerboard(int[][] array) { + for (int horl = 0;horl < 3; horl++) { + for (int verl = 0;verl < 3; verl++) { + array[horl][verl] = NOT_USE; + } + } + } + + private static void gameTimer() { + timer = new Timer(); + timer.schedule(new TimerTask() { + public void run() { + midTime--; + if (!countDownSwitch) { + myTaskDis.asyncDispatch(()-> roPrbar.setProgressValue(0)); + timer.cancel(); + return; + } + if (midTime >= 0) { + runImg(imageMe); + myTaskDis.asyncDispatch(()-> { + roPrbar.setProgressValue(midTime); + String sTime=String.valueOf(midTime); + roPrbar.setProgressHintText(sTime); + }); + } else { + timer.cancel(); + myTaskDis.asyncDispatch(() -> { + GameStatusUtils.showFaild(StartAbilitySlice.image1.getContext()); + btnRefreshFlag = true; + imageRefresh.setPixelMap(ResourceTable.Media_icon_refresh); + btnBackFlag = true; + imageBack.setPixelMap(ResourceTable.Media_icon_back); + gameOver(); + if (myProxy != null) { + myProxy.sendCmd(GAME_COM_WIN); + } + }); + } + } + }, 0, 1000); + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/DeviceSelectDialog.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/DeviceSelectDialog.java new file mode 100755 index 0000000000000000000000000000000000000000..86290bde3371d0821f636e2d0c41e438820c7192 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/DeviceSelectDialog.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.ui; + +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.ListContainer; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.app.Context; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.samples.tictactoegame.ResourceTable; +import ohos.samples.tictactoegame.data.mode.DeviceData; +import ohos.samples.tictactoegame.ui.listcomponent.CommentViewHolder; +import ohos.samples.tictactoegame.ui.listcomponent.ListComponentAdapter; +import ohos.samples.tictactoegame.utils.DeviceUtils; + +import java.util.ArrayList; +import java.util.List; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +public class DeviceSelectDialog extends CommonDialog { + private DeviceInfo mCheckedDevice; + private ListContainer mListContainer; + private final List mDeviceList = new ArrayList<>(); + private ListComponentAdapter listComponentAdapter; + public interface OnclickListener { + void onYesClick(DeviceInfo deviceInfo); + } + + private final Context mContext; + private OnclickListener mOnclickListener; + + public DeviceSelectDialog(Context context) { + super(context); + this.mContext = context; + + } + + public void setListener(OnclickListener listener) { + mOnclickListener = listener; + } + @Override + protected void onCreate() { + super.onCreate(); + Component rootView = + LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_dialog_layout_device, null, false); + mListContainer = (ListContainer) rootView.findComponentById(ResourceTable.Id_list_container_device); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_operate_yes); + Text operateNo = (Text) rootView.findComponentById(ResourceTable.Id_operate_no); + + List deviceInfoList = DeviceUtils.getRemoteDevice(); + mDeviceList.clear(); + for (DeviceInfo deviceInfo : deviceInfoList) { + mDeviceList.add(new DeviceData(false, deviceInfo)); + } + if (deviceInfoList.size() > 0) { + mCheckedDevice = deviceInfoList.get(0); + } + mListContainer.setItemProvider(listComponentAdapter = new ListComponentAdapter(mContext, mDeviceList, ResourceTable.Layout_dialog_device_item) { + @Override + public void onBindViewHolder(CommentViewHolder commonViewHolder, DeviceData item, int position) { + commonViewHolder.getTextView(ResourceTable.Id_item_desc).setText(item.getDeviceInfo().getDeviceName()); + switch (item.getDeviceInfo().getDeviceType()) { + case SMART_PHONE: + commonViewHolder.getImageView(ResourceTable.Id_item_type).setPixelMap(ResourceTable.Media_dv_phone); + break; + case SMART_PAD: + commonViewHolder.getImageView(ResourceTable.Id_item_type).setPixelMap(ResourceTable.Media_dv_pad); + break; + case SMART_WATCH: + commonViewHolder.getImageView(ResourceTable.Id_item_type).setPixelMap(ResourceTable.Media_dv_watch); + break; + } + commonViewHolder.getImageView(ResourceTable.Id_item_check).setPixelMap(item.isChecked() ? ResourceTable.Media_checked_point : ResourceTable.Media_uncheck_point); + } + + @Override + public void onItemClick(Component component, DeviceData item, int position) { + super.onItemClick(component, item, position); + for (DeviceData deviceData : mDeviceList) { + deviceData.setChecked(false); + } + mDeviceList.get(position).setChecked(true); + listComponentAdapter.notifyDataChanged(); + mCheckedDevice = item.getDeviceInfo(); + } + }); + + operateYes.setClickedListener(component -> { + if (mOnclickListener != null && mCheckedDevice != null) { + mOnclickListener.onYesClick(mCheckedDevice); + } + }); + operateNo.setClickedListener(component -> hide()); + + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.BOTTOM); + setCornerRadius(10); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/CommentViewHolder.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/CommentViewHolder.java new file mode 100755 index 0000000000000000000000000000000000000000..6b5ad25cbd265e5d18ddf50778104288a43e8f7e --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/CommentViewHolder.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.ui.listcomponent; + +import ohos.agp.components.Component; +import ohos.agp.components.Image; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.app.Context; + +import java.util.HashMap; +import java.util.Map; + +public class CommentViewHolder { + // Use singleton mode to avoid multiple static classes + + public static CommentViewHolder getCommentViewHolder(Context context, Component convertView, int resource) { + + if (convertView == null) { + + convertView = LayoutScatter.getInstance(context).parse(resource, null, false); + return new CommentViewHolder(convertView); + } else { + + return (CommentViewHolder) convertView.getTag(); + } + } + + public Component convertView; + + // 对成员变量赋值,并把当前CommentViewHolder用tag存起来以便复用 + + public CommentViewHolder(Component convertView) { + + this.convertView = convertView; + convertView.setTag(this); + } + + private final Map mViews = new HashMap<>(); + + // 根据xml的控件的资源id从集合里面取出对应控件 + + public T getView(int resId) { + + Component view = mViews.get(resId); + if (view == null) { + + view = convertView.findComponentById(resId); + mViews.put(resId, view); + } + return (T) view; + } + + // 根据泛型,指定view的类型 + + public T getView(int resId, Class type) { + + Component view = mViews.get(resId); + if (view == null) { + + view = convertView.findComponentById(resId); + mViews.put(resId, view); + } + return (T) view; + } + + // 2个常用的view,简单处理一下对外提供出来 + + public Text getTextView(int resId) { + + return getView(resId, Text.class); + } + + public Image getImageView(int resId) { + + return getView(resId, Image.class); + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/ListComponentAdapter.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/ListComponentAdapter.java new file mode 100755 index 0000000000000000000000000000000000000000..99fa6c9acf5c93dea5986ab5e0fce170665b452e --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/ui/listcomponent/ListComponentAdapter.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.ui.listcomponent; + +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.RecycleItemProvider; +import ohos.app.Context; + +import java.util.List; + +public abstract class ListComponentAdapter extends RecycleItemProvider { + private final Context mContext; + private final List mListBean; + private final int mXmlId; + + public abstract void onBindViewHolder(CommentViewHolder commonViewHolder, T item, int position); + + public ListComponentAdapter(Context context, List list, int xmlId) { + this.mContext = context; + this.mListBean = list; + this.mXmlId = xmlId; + layoutScatter = LayoutScatter.getInstance(mContext); + } + + @Override + public int getCount() { + return mListBean.size(); + } + + @Override + public T getItem(int i) { + return mListBean.get(i); + } + + @Override + public long getItemId(int i) { + return i; + } + + LayoutScatter layoutScatter; + + @Override + public Component getComponent(int i, Component component, ComponentContainer componentContainer) { + CommentViewHolder commentViewHolder = CommentViewHolder.getCommentViewHolder(mContext, component, mXmlId); + T t = mListBean.get(i); + + onBindViewHolder(commentViewHolder, t, i); + commentViewHolder.convertView.setClickedListener(component1 -> onItemClick(component,t,i)); + return commentViewHolder.convertView; + } + + + public void onItemClick(Component component, T item, int position){ + + } +} \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/DeviceUtils.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/DeviceUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..f755bfa9984c6ab50f10447e5daa425b0ad0e4fe --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/DeviceUtils.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.utils; + +import ohos.account.AccountAbility; +import ohos.account.DistributedInfo; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.distributedschedule.interwork.DeviceManager; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceUtils { + private DeviceUtils() {} + + /** + * Get group id. + * @return group id. + */ + public static String getGroupId() { + AccountAbility account = AccountAbility.getAccountAbility(); + DistributedInfo distributeInfo = account.queryOsAccountDistributedInfo(); + return distributeInfo.getId(); + } + + public static List getAvailableDeviceId() { + List deviceIds = new ArrayList<>(); + + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + if (deviceInfoList == null) { + return deviceIds; + } + + if (deviceInfoList.size() == 0) { + return deviceIds; + } + + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceIds.add(deviceInfo.getDeviceId()); + } + + return deviceIds; + } + + /** + * Get available id + * @return available device ids + */ + public static List getAllAvailableDeviceId() { + List deviceIds = new ArrayList<>(); + + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ALL_DEVICE); + if (deviceInfoList == null) { + return deviceIds; + } + System.out.println("deviceInfoList size " + deviceInfoList.size()); + if (deviceInfoList.size() == 0) { + System.out.println("did not find other device"); + return deviceIds; + } + + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceIds.add(deviceInfo.getDeviceId()); + } + + return deviceIds; + } + + /** + * Get remote device info + * @return Remote device info list. + */ + public static List getRemoteDevice() { + return DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + } + + /** + * @Params [] + * @description Obtain the device ID that can be migrated under the current networking + * @return java.lang.String + */ + public static String getDeviceId() { + String deviceId = ""; + List outerDevices = DeviceUtils.getAvailableDeviceId(); + System.out.println("getDeviceId DeviceUtils.getRemoteDevice() = " + outerDevices); + if (outerDevices.size() == 0) { + System.out.println( "no other device to continue"); + }else { + for (String item : outerDevices) { + System.out.println( "item deviceId = " + item); + } + deviceId = outerDevices.get(0); + } + System.out.println("continueAbility to deviceId = " + deviceId); + return deviceId; + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameRulesUtils.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameRulesUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..889dab297c0a9d0bc5afbf68aa11ab7259e799bb --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameRulesUtils.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.utils; + +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.app.Context; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.samples.tictactoegame.ResourceTable; +import ohos.samples.tictactoegame.ui.DeviceSelectDialog; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +public class GameRulesUtils extends CommonDialog { + + /** + * Set the OK button and cancel the clicked interface + */ + public interface OnclickListener { + void onYesClick(DeviceInfo deviceInfo); + } + + private final Context mContext; + private DeviceSelectDialog.OnclickListener mOnclickListener; + + public GameRulesUtils(Context context) { + super(context); + this.mContext = context; + + } + + public void setListener(DeviceSelectDialog.OnclickListener listener) { + mOnclickListener = listener; + } + + @Override + protected void onCreate() { + super.onCreate(); + Component rootView = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_dialog_game_rule, null, false); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_rule_yes); + operateYes.setClickedListener(component -> hide()); + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.BOTTOM); + setCornerRadius(10); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameStatusUtils.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameStatusUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..6eee9da8ca0a6fa41c66dd72cc3f13db884f9286 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/GameStatusUtils.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.utils; + +import ohos.agp.components.DirectionalLayout; +import ohos.agp.components.Image; +import ohos.agp.components.LayoutScatter; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; +import ohos.samples.tictactoegame.ResourceTable; + +public class GameStatusUtils { + + private static final int DIS_FAILED = 0; + private static final int DIS_WIN = 1; + private static final int DIS_TIE = 3; + + public static void showTip(Context mContext, int durationTime, int flag) { + DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(mContext) + .parse(ResourceTable.Layout_game_status, null, false); + + Image img = (Image) toastLayout.findComponentById(ResourceTable.Id_img_gameStatus); + if (flag == DIS_FAILED) { + img.setPixelMap(ResourceTable.Media_game_fail); + } + if (flag == DIS_WIN) { + img.setPixelMap(ResourceTable.Media_game_win); + } + if (flag == DIS_TIE) { + img.setPixelMap(ResourceTable.Media_game_tie); + } + new ToastDialog(mContext) + .setComponent(toastLayout) + .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT) + .setAlignment(LayoutAlignment.CENTER) + .setDuration(durationTime) + .show(); + } + public static void showWin(Context mContext) { + showTip(mContext,1000, DIS_WIN); + } + public static void showFaild(Context mContext) { + showTip(mContext,1000, DIS_FAILED); + } + public static void showTie(Context mContext) { + showTip(mContext,1000, DIS_TIE); + } +} + diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/PkUtils.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/PkUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..fe35fd76c213d6da8c1863dd66ebdba1a9240199 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/PkUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.utils; + +import ohos.agp.components.DirectionalLayout; +import ohos.agp.components.LayoutScatter; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; +import ohos.samples.tictactoegame.ResourceTable; + +public class PkUtils { + public static void showTip(Context context, int durationTime) { + DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(context) + .parse(ResourceTable.Layout_layout_toast, null, false); + new ToastDialog(context) + .setComponent(toastLayout) + .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT) + .setAlignment(LayoutAlignment.CENTER) + .show(); + } + public static void showTip(Context context) { + showTip(context,1000); + } +} diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/UIUtils.java b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/UIUtils.java new file mode 100755 index 0000000000000000000000000000000000000000..00827082fd24fa6694f0f329b862bfd1462a1d5c --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/java/ohos/samples/tictactoegame/utils/UIUtils.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd.All rights reserved. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.tictactoegame.utils; + +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; + +public class UIUtils { + public static void showTip(Context context, String msg) { + ToastDialog toastDialog = new ToastDialog(context); + toastDialog.setText(msg); + toastDialog.setAlignment(LayoutAlignment.CENTER); + toastDialog.show(); + } +} \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/element/string.json b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000000000000000000000000000000000..d66d7e3d6800025ac6558aa34f57f9bc35e0b811 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/element/string.json @@ -0,0 +1,52 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "TicTacToeGame" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "Hello World" + }, + { + "name": "remoteserviceability_description", + "value": "hap sample empty service" + }, + { + "name": "title_label", + "value": "Tic tac toe battle" + }, + { + "name": "game_rules", + "value": "Rules" + }, + { + "name": "game_start_label", + "value": "Start" + }, + { + "name": "rules_info", + "value": "Two players, one with a circle (o) and one with a cross (x), take turns to play their own symbols on the grid of 3 by 3. If they are first connected into a line horizontally, vertically and obliquely, they will win. If both sides play correctly, they will be drawn. This game is actually controlled by the first player. The first player is attacking and the second player is defending." + }, + { + "name": "rules_info1", + "value": "If the first player is the first player in the corner position, he will win the most. If the second player is in the side position, the first player can tie down the second player with two wires, and then create \"two snakes\". People who have played this game will find that if both players make the best choice, the game will be tied. Therefore, tic tac toe chess is most often used as a children's game." + }, + { + "name": "confirm_label", + "value": "Confirm" + }, + { + "name": "cancel_label", + "value": "Cancel" + }, + { + "name": "add_device_label", + "value": "Add game device" + } + ] +} \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_ability_main.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100755 index 0000000000000000000000000000000000000000..67c88bc795280733fc188db5f1f60e2013ef9129 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_button_radius_.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_button_radius_.xml new file mode 100755 index 0000000000000000000000000000000000000000..d8f85f0e748f951cbb736a84f8cfff17d5d7425d --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_button_radius_.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_game_rule.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_game_rule.xml new file mode 100755 index 0000000000000000000000000000000000000000..94ed5ad3bd39f1721657b07002b0df02dce2498a --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_game_rule.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_rule_yes.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_rule_yes.xml new file mode 100755 index 0000000000000000000000000000000000000000..3c4ca811a1bb6dc47b4d91e99a384c25e80081f1 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_rule_yes.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_toast_element.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_toast_element.xml new file mode 100755 index 0000000000000000000000000000000000000000..b87f497da26c478c7392586a703f2080306841bd --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_toast_element.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_white_radius_10.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_white_radius_10.xml new file mode 100755 index 0000000000000000000000000000000000000000..d9aab8d680b9c4fbaede6d21125a40e9c636d754 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/graphic/background_white_radius_10.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/layout/ability_main.xml b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/layout/ability_main.xml new file mode 100755 index 0000000000000000000000000000000000000000..3eb1025409e9bb91d4f8d0945f026e92459c1e97 --- /dev/null +++ b/ScenarioDemos/TicTacToeGame/entry/src/main/resources/base/layout/ability_main.xml @@ -0,0 +1,85 @@ + + + + + + + +