From 06247d338ef9d5a90c84af2a9fed901e08b3e03b Mon Sep 17 00:00:00 2001 From: wangshi Date: Thu, 23 Jan 2025 16:38:52 +0800 Subject: [PATCH 1/4] add p2p app Signed-off-by: wangshi --- .../wifi/p2ptest/AppScope/app.json5 | 25 ++++++++++++++++++ .../resources/base/element/string.json | 8 ++++++ .../resources/base/media/app_icon.png | Bin 0 -> 2041 bytes 3 files changed, 33 insertions(+) create mode 100644 function/communication/wifi/p2ptest/AppScope/app.json5 create mode 100644 function/communication/wifi/p2ptest/AppScope/resources/base/element/string.json create mode 100644 function/communication/wifi/p2ptest/AppScope/resources/base/media/app_icon.png diff --git a/function/communication/wifi/p2ptest/AppScope/app.json5 b/function/communication/wifi/p2ptest/AppScope/app.json5 new file mode 100644 index 000000000..f3d3db46b --- /dev/null +++ b/function/communication/wifi/p2ptest/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "app": { + "bundleName": "com.example.wifip2p", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/function/communication/wifi/p2ptest/AppScope/resources/base/element/string.json b/function/communication/wifi/p2ptest/AppScope/resources/base/element/string.json new file mode 100644 index 000000000..1ece574c1 --- /dev/null +++ b/function/communication/wifi/p2ptest/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "wifiP2P" + } + ] +} diff --git a/function/communication/wifi/p2ptest/AppScope/resources/base/media/app_icon.png b/function/communication/wifi/p2ptest/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 -- Gitee From 3bba7be782285cd9c9817f8aad14a0dcb82c1fe4 Mon Sep 17 00:00:00 2001 From: wangshi Date: Thu, 23 Jan 2025 16:39:14 +0800 Subject: [PATCH 2/4] add p2p app Signed-off-by: wangshi --- .../wifi/p2ptest/entry/.gitignore | 6 + .../wifi/p2ptest/entry/build-profile.json5 | 51 ++ .../wifi/p2ptest/entry/hvigorfile.ts | 21 + .../wifi/p2ptest/entry/obfuscation-rules.txt | 18 + .../wifi/p2ptest/entry/oh-package.json5 | 25 + .../main/ets/entryability/EntryAbility.ets | 58 ++ .../entry/src/main/ets/pages/Index.ets | 541 ++++++++++++++++++ .../entry/src/main/ets/workers/Worker.ets | 205 +++++++ .../wifi/p2ptest/entry/src/main/module.json5 | 78 +++ .../main/resources/base/element/color.json | 237 ++++++++ .../main/resources/base/element/string.json | 28 + .../src/main/resources/base/media/icon.png | Bin 0 -> 2041 bytes .../main/resources/base/media/startIcon.png | Bin 0 -> 4351 bytes .../resources/base/profile/main_pages.json | 5 + .../main/resources/en_US/element/string.json | 28 + .../main/resources/zh_CN/element/string.json | 28 + .../p2ptest/entry/src/mock/mock-config.json5 | 17 + .../src/ohosTest/ets/test/Ability.test.ets | 50 ++ .../entry/src/ohosTest/ets/test/List.test.ets | 20 + .../ohosTest/ets/testability/TestAbility.ets | 64 +++ .../ohosTest/ets/testability/pages/Index.ets | 32 ++ .../ets/testrunner/OpenHarmonyTestRunner.ets | 107 ++++ .../p2ptest/entry/src/ohosTest/module.json5 | 52 ++ .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 + .../ohosTest/resources/base/media/icon.png | Bin 0 -> 2041 bytes .../resources/base/profile/test_pages.json | 5 + .../wifi/p2ptest/entry/src/test/List.test.ets | 20 + .../p2ptest/entry/src/test/LocalUnit.test.ets | 48 ++ 29 files changed, 1768 insertions(+) create mode 100644 function/communication/wifi/p2ptest/entry/.gitignore create mode 100644 function/communication/wifi/p2ptest/entry/build-profile.json5 create mode 100644 function/communication/wifi/p2ptest/entry/hvigorfile.ts create mode 100644 function/communication/wifi/p2ptest/entry/obfuscation-rules.txt create mode 100644 function/communication/wifi/p2ptest/entry/oh-package.json5 create mode 100644 function/communication/wifi/p2ptest/entry/src/main/ets/entryability/EntryAbility.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/main/ets/pages/Index.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/main/ets/workers/Worker.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/main/module.json5 create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/base/element/color.json create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/base/element/string.json create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/base/media/icon.png create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/base/media/startIcon.png create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/base/profile/main_pages.json create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/en_US/element/string.json create mode 100644 function/communication/wifi/p2ptest/entry/src/main/resources/zh_CN/element/string.json create mode 100644 function/communication/wifi/p2ptest/entry/src/mock/mock-config.json5 create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/Ability.test.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/List.test.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/TestAbility.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/pages/Index.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/module.json5 create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/color.json create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/string.json create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/media/icon.png create mode 100644 function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/profile/test_pages.json create mode 100644 function/communication/wifi/p2ptest/entry/src/test/List.test.ets create mode 100644 function/communication/wifi/p2ptest/entry/src/test/LocalUnit.test.ets diff --git a/function/communication/wifi/p2ptest/entry/.gitignore b/function/communication/wifi/p2ptest/entry/.gitignore new file mode 100644 index 000000000..e2713a277 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/build-profile.json5 b/function/communication/wifi/p2ptest/entry/build-profile.json5 new file mode 100644 index 000000000..9db92f242 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/build-profile.json5 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "apiType": "stageMode", + "buildOption": { + "arkOptions": { + // "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */ + }, + "sourceOption": { + "workers": [ + './src/main/ets/workers/Worker.ets' + ] + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/hvigorfile.ts b/function/communication/wifi/p2ptest/entry/hvigorfile.ts new file mode 100644 index 000000000..062d98c98 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/function/communication/wifi/p2ptest/entry/obfuscation-rules.txt b/function/communication/wifi/p2ptest/entry/obfuscation-rules.txt new file mode 100644 index 000000000..985b2aeb7 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/oh-package.json5 b/function/communication/wifi/p2ptest/entry/oh-package.json5 new file mode 100644 index 000000000..56c084745 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/oh-package.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/function/communication/wifi/p2ptest/entry/src/main/ets/entryability/EntryAbility.ets b/function/communication/wifi/p2ptest/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 000000000..41b706a61 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/function/communication/wifi/p2ptest/entry/src/main/ets/pages/Index.ets b/function/communication/wifi/p2ptest/entry/src/main/ets/pages/Index.ets new file mode 100644 index 000000000..a09db4917 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,541 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 wifiManager from '@ohos.wifiManager'; +import { BusinessError } from '@ohos.base'; +import { WorkerParam, WorkParam } from '.././workers/Worker'; +import socket from '@ohos.net.socket'; +import worker, { MessageEvents, ErrorEvent } from '@ohos.worker'; + +@Component +export struct TitleBar { + private title!: string; + build() { + Column() { + Row() { + Text(this.title) + .fontSize(20) + .layoutWeight(1) + .margin({ left: 16 }) + .align(Alignment.Start) + Blank() + } + .height(56) + .width('100%') + } + } +} + +@Extend(Column) +function backgroundStyle() { + .width('100%') + .padding(12) + .borderRadius(16) + .backgroundColor(Color.White) + .justifyContent(FlexAlign.SpaceAround) +} + +@Entry +@Component +struct Index { + @State cliButText: string = '测试客户端'; + @State serButText: string = '测试服务端'; + @State serEnabled: boolean = true; + @State sendCnt: string = '100'; //传输次数 + @State cntIndex: number = 1; + @State packageSize: string = '1024'; //包长 + @State packageIndex: number = 1; + @State logButColor: Color = Color.White; + @State serColor: Color = Color.Blue; + @State debug: boolean = false; + @State logCnt: number = 0; + @State numberArray: number[] = []; //服务端接收次序 + @State messageArr: Array = []; //服务端收包字长数组 + @State deltaDateArr: Array = []; //服务端收包时间数组 + @State packageNumArr: Array = []; //服务端收包个数数组 + @State velocityArr: Array = []; //传输速率数组 + @State acceptNum: number = 0; //服务端收包次数 + @State packageNum: number = 0; //服务端收包个数 + @State len: number = 0; //服务端每次收到字长 + @State deltaDate: number = 0; //服务端每次收包时间 + @State velocity: number = 0; + @State zeroLength: number = 0; //服务端接收的0的字长 + @State oneItem: number = 0; //数组中1的索引 + @State workParam: WorkParam = { + cliButtText: '测试客户端', + cliColor: Color.Blue, + numArr: [], + packArr: [], + messArr: [], + cliCnt: 0, + cliPack: 0, + cliLen: 0, + cliBol: true + } + @State starttime: number = 0; + @State endtime: number = 0; + @State recvSize: number = 0; //服务端接收总字长 + @State recvDuration: number = 0; //服务端总计时 + @State recvPackageNum: number = 0; + @State listDirection: Axis = Axis.Vertical; + @State space: number = 10; + @State strokeWidth: number = 0; + @State color: string = '#409EFF'; + @State barState: BarState = BarState.Auto; + @State scrollBarWidth: number = 0; + @State scrollBarColor: Color = Color.Blue; + @State initIndex: number = AppStorage.get('listSampleInitIndex') || 0; + @State edgeEffect: EdgeEffect = EdgeEffect.Spring; + @State isChainAnimation: boolean = false; + @State multiSelectable: boolean = false; + @State lanes: number = 1; + @State alignListItem: ListItemAlign = ListItemAlign.Center; + private controller: Scroller = new Scroller(); + private dataArr: Uint8Array = new Uint8Array(); + udp: socket.UDPSocket = socket.constructUDPSocketInstance(); // 创建一个UDPSocket对象 + private udpextraoptions: socket.UDPExtraOptions = { + receiveBufferSize: 1000, + sendBufferSize: 1000, + reuseAddress: false, + socketTimeout: 6000, + broadcast: true + } + + print(msg: string) { + if (this.debug) { + console.log(msg); + } + } + + recvP2pPersistentGroupChangeFunc = () => { + console.info("p2p persistent group change receive event"); + // 永久组创建好后需要处理的业务 + this.getCurrentP2P(); + this.createUdpSocket(); + } + + getCurrentP2P() { + let ipinfo = wifiManager.getIpInfo(); // 获取IP信息 + this.print(`ipinfo: ${JSON.stringify(ipinfo)}`); + this.print(`ipaddr: ${this.intToIp(ipinfo.ipAddress)}`); + // 获取P2P连接信息 + wifiManager.getP2pLinkedInfo().then((p2pInfo) => { + this.print(`p2plinkedinfo: ${JSON.stringify(p2pInfo)}`); + }) + // 获取P2P当前组信息 + wifiManager.getCurrentGroup().then((data: wifiManager.WifiP2pGroupInfo) => { + this.print(`get current P2P group: ${JSON.stringify(data)}`); + if (data.isP2pGo && data.groupName === 'ANOV') { + this.print(`WifiP2pGroupInfo is: ${JSON.stringify(data)}`); + } + }) + .catch((err: BusinessError) => { + console.log(`getCurrentGroup: ${JSON.stringify(err)}`); + }) + } + + createUdpSocket() { + // 设置UDPSocket连接的其他属性 + this.udp.setExtraOptions(this.udpextraoptions, (err: BusinessError) => { + console.log(`setExtraOptions res: ${JSON.stringify(err)}`); + }); + // 目标地址信息 + let bindAddr: socket.NetAddress = { + address: "0.0.0.0", + port: 1101 + } + this.udp.on('message', (data) => { + this.onMessage(data.message); + }) + // 订阅UDPSocket连接的数据包消息事件 + this.udp.on('listening', () => { + this.print("on listening success"); + }); + // 订阅UDPSocket连接的error事件 + this.udp.on('error', (err) => { + console.log(`on udp err: ${JSON.stringify(err)}`); + }) + // 绑定IP地址和端口 + this.udp.bind(bindAddr).then(() => { + this.print(`bind success: ${JSON.stringify(bindAddr)}`); + }).catch((err: BusinessError) => { + console.log('bind fail, err: ' + JSON.stringify(err)); + }) + } + + // 转IP地址 + intToIp(int: number) { + // 将整数转换为32位二进制字符串 + const binaryString = int.toString(2).padStart(32, '0'); + + // 分割二进制字符串为四个8位的段 + const octet1 = binaryString.substring(0, 8); + const octet2 = binaryString.substring(8, 16); + const octet3 = binaryString.substring(16, 24); + const octet4 = binaryString.substring(24, 32); + + // 将每个8位的段转换为十进制数 + const octet1Dec = Number.parseInt(octet1, 2); + const octet2Dec = Number.parseInt(octet2, 2); + const octet3Dec = Number.parseInt(octet3, 2); + const octet4Dec = Number.parseInt(octet4, 2); + + // 组合四个十进制数成为IP地址 + const ipAddress = `${octet1Dec}.${octet2Dec}.${octet3Dec}.${octet4Dec}`; + + return ipAddress; + } + + printMess() { + this.print(`============第${this.acceptNum}次接收数据============`); + this.print(`data[0] = ${this.dataArr[0]}, data.length is ${this.dataArr.length}`); + this.print(`this.len is ${this.len}`); + } + + startInit() { + this.starttime = new Date().getTime(); + this.acceptNum++; + } + + endCalculate() { + this.endtime = new Date().getTime(); + this.deltaDate = this.endtime - this.starttime; + this.len += this.dataArr.length; + this.velocity = this.len * 1000 / (this.deltaDate * 1024); + this.packageNum++; + this.printMess(); + this.print(`endtime is ${this.endtime}`); + this.print(`this.deltaDate is ${this.deltaDate}`); + this.numberArray.push(this.acceptNum); + this.packageNumArr.push(this.packageNum); + this.messageArr.push(this.len); + this.deltaDateArr.push(this.deltaDate); + this.velocityArr.push(this.velocity); + this.recvDuration += this.deltaDate; //总计时 + this.recvSize += this.len; //总字长 + this.recvPackageNum += this.packageNum; //总收包 + this.starttime = 0; + this.endtime = 0; + this.len = 0; + this.packageNum = 0; + } + + onMessage(dataBuffer: ArrayBuffer) { + this.dataArr = new Uint8Array(dataBuffer); + if (this.dataArr[0] === 0) { + this.startInit(); + this.printMess(); + return; + } + if (this.dataArr[0] === 100) { + this.endCalculate(); + return; + } + if (this.dataArr[0] === 199) { + this.serButText = '测试服务端'; + this.serColor = Color.Blue; + this.serEnabled = true; + wifiManager.removeGroup(); + this.print('移除群组!'); + this.udp.close(); + this.print('关闭UDPSocket连接!'); + return; + } + this.len += this.dataArr.length; + this.packageNum++; + this.printMess(); + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) { + TitleBar({ title: 'wifiP2P测试' }) + .flexGrow(0) + .onClick(() => { + this.logCnt++; + if (this.logCnt % 2 === 0) { + this.debug = false; + } else { + this.debug = true; + } + if (this.debug) { + this.logButColor = Color.Pink; + } else { + this.logButColor = Color.White; + } + }) + .backgroundColor(this.logButColor) + + // tab页签 + Column() { + Tabs({ barPosition: BarPosition.Start }) { + // 子页签:WaterFlow控制 + TabContent() { + Column() { + Row() { + Text('次数') + Select([{ value: '1'}, { value: '10' }, { value: '100' }, { value: '1000' }]) + .value(this.sendCnt) + .backgroundColor(Color.White) + .borderRadius(19) + .constraintSize({ minWidth: 100 }) + .selected(this.cntIndex) + .onSelect((index, value) => { + this.cntIndex = index; + this.sendCnt = value; + }) + .width(50) + .margin(10) + .borderRadius(2) + + Text('长度') + Select([{ value: '10' }, { value: '1024' }, { value: '4096' }]) + .value(this.packageSize) + .backgroundColor(Color.White) + .borderRadius(19) + .constraintSize({ minWidth: 100 }) + .selected(this.packageIndex) + .onSelect((index, value) => { + this.packageIndex = index; + this.packageSize = value; + }) + .margin(10) + .borderRadius(2) + } + + // 客户端按钮 + Button(this.workParam.cliButtText) + .height(50) + .width('80%') + .onClick(() => { + this.workParam.cliButtText = '测试中......'; + this.workParam.cliBol = false; + this.workParam.cliColor = Color.Grey; + this.acceptNum = 0; + this.len = 0; + this.numberArray.length = 0;//服务端切至客户端清除收包信息列表 + this.workParam.numArr.length = 0; + this.workParam.cliCnt = 0; + this.workParam.cliPack = 0; + this.workParam.cliLen = 0; + this.workParam.cliBol = false; + // 主线程中创建Worker对象 + const workerInstance = new worker.ThreadWorker('entry/ets/workers/Worker.ets'); + let workerParam: WorkerParam = { + cnt: Number(this.sendCnt), + packageSize: Number(this.packageSize), + debug: this.debug + } + let paramStr = JSON.stringify(workerParam); + // 主线程向worker线程传递信息 + workerInstance.postMessage(paramStr); + // 主线程接收worker线程信息 + workerInstance.onmessage = (e: MessageEvents): void => { + this.print('main thread onmessage'); + // data:worker线程发送的信息 + let data: WorkParam = JSON.parse(e.data) + this.workParam = data; + } + workerInstance.onerror = (err: ErrorEvent) => { + this.print('main error message ' + err.message); + } + }) + .backgroundColor(this.workParam.cliColor) + .enabled(this.workParam.cliBol) + .stateEffect(true) + } + .height('100%') + }.tabBar(new SubTabBarStyle($r('app.string.wifiP2P_client'))) + + // 子页签:WaterFlow属性 + TabContent() { + Column() { + //服务端按钮 + Button(this.serButText) + .height(50) + .width('80%') + .onClick(() => { + this.serButText = '测试中......'; + this.serEnabled = false; + this.serColor = Color.Grey; + this.workParam.cliCnt = 0; + this.workParam.cliPack = 0; + this.workParam.cliLen = 0; + this.workParam.numArr.length = 0; + this.workParam.packArr.length = 0; + this.workParam.messArr.length = 0; + this.messageArr.length = 0; + this.numberArray.length = 0; + this.deltaDateArr.length = 0; + this.packageNumArr.length = 0; + this.velocityArr.length = 0; + this.messageArr.length = 0; + this.len = 0; + this.packageNum = 0; + this.recvSize = 0; + this.recvDuration = 0; + this.recvPackageNum = 0; + this.acceptNum = 0; + wifiManager.on("p2pPersistentGroupChange", this.recvP2pPersistentGroupChangeFunc); + try { + let config: wifiManager.WifiP2PConfig = { + deviceAddress: "11:33:11:44:77:44", + deviceAddressType: 1, // 设备地址类型,0:随机;1:真实地址; + netId: -1, // 临时创建群组,-1:临时组;-2:永久组; + passphrase: "11223344", + groupName: "ANOV", + goBand: 1 // 信道带宽 2.4GHz + } + wifiManager.createGroup(config); + } catch(error) { + console.error("failed:" + JSON.stringify(error)); + } + }) + .backgroundColor(this.serColor) + .enabled(this.serEnabled) + .stateEffect(true) + } + .height('100%') + }.tabBar(new SubTabBarStyle($r('app.string.wifiP2P_server'))) + } + .vertical(false) + .scrollable(true) + .barMode(BarMode.Fixed) + .backgroundColor(Color.Pink) + .onChange((index: number) => { + console.info(index.toString()) + }) + .width('100%') + .backgroundColor(0xF1F3F5) + } + .height('30%') + .width('100%') + + // List + Column() { + //客户端发送信息列表 + List({ scroller: this.controller, initialIndex: this.initIndex, space: this.space }) { + ForEach(this.workParam.numArr, (item: number, index: number) => { + ListItem() { + Column() { + Text(`第${ this.workParam.numArr[item-1] }次,发包${ this.workParam.packArr[item-1] }个,长${ + this.workParam.messArr[item-1] }字节`) + .margin(5) + .width('90%') + .align(Alignment.Center) + .textAlign(TextAlign.Center) + } + .width('100%') + .backgroundColor('#0d000000') + .height(40) + } + }) + } + + //服务端接收信息列表 + List({ scroller: this.controller, initialIndex: this.initIndex, space: this.space }) { + ForEach(this.numberArray, (item: number, index: number) => { + ListItem() { + Column() { + Text(`第${this.numberArray[item-1]}次,收包${ this.packageNumArr[item-1] }个,长${this.messageArr[item-1]}字节`) + .margin(5) + .width('90%') + .align(Alignment.TopStart) + .textAlign(TextAlign.Start) + Text(`用时${this.deltaDateArr[item-1]}毫秒,速度${ Math.round(this.velocityArr[item-1]) } KB/s`) + .margin(5) + .width('90%') + .align(Alignment.BottomEnd) + .textAlign(TextAlign.End) + } + .width('100%') + .backgroundColor('#0d000000') + .height(60) + } + }) + } + .alignListItem(this.alignListItem) + .height('100%') + .width('100%') + .listDirection(this.listDirection) + .scrollBar(this.barState) + .scrollBarColor(this.scrollBarColor) + .scrollBarWidth(this.scrollBarWidth) + .edgeEffect(this.edgeEffect) + .multiSelectable(this.multiSelectable) + .chainAnimation(this.isChainAnimation) + .lanes(this.lanes) + .divider( + { + strokeWidth: this.strokeWidth, + color: this.color + } + ) + } + .padding({ left: 12, right: 12 }) + .backgroundStyle() + .height('40%') + .width('100%') + .flexGrow(0) + + Column() { + if (this.acceptNum !== 0) { + Text() { + Span(`共测试次数: ${this.acceptNum}`) + } + + Text(`共收到字节: ${this.recvSize}字节`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + + Text(`共收到包数: ${this.recvPackageNum}`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + + Text(`总计时: ${(this.recvDuration * 0.001).toFixed(6)}s`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + + Text(`平均速度:${Math.round(this.recvSize * 1000 / (this.recvDuration * 1024))}KB/s`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + } + + if (this.workParam.cliCnt !== 0) { + Text() { + Span(`共测试次数: ${this.workParam.cliCnt}`) + } + + Text(`共发送包数: ${this.workParam.cliPack}`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + + Text(`共发送字节: ${this.workParam.cliLen}字节`) + .textAlign(TextAlign.Start) + .fontColor(Color.Gray) + } + } + .height('16%') + .width('100%') + .padding({left:12}) + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Center) + .flexGrow(0) + } + .padding({ left: 12, right: 12 }) + .height('100%') + .width('100%') + .backgroundColor('$color:index_background') + } +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/ets/workers/Worker.ets b/function/communication/wifi/p2ptest/entry/src/main/ets/workers/Worker.ets new file mode 100644 index 000000000..55ef988ec --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/ets/workers/Worker.ets @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker'; +import { BusinessError } from '@ohos.base'; +import connection from '@ohos.net.connection'; +import wifiManager from '@ohos.wifiManager'; +import socket from '@ohos.net.socket'; + +export interface WorkerParam { + cnt: number; + packageSize: number; + debug: boolean; +} + +export interface WorkParam { + cliButtText: string; //客户端按钮文本 + cliColor: Color; //客户端按钮颜色 + numArr: Array; //发送数据次数 + packArr: Array; //每次发包个数 + messArr: Array; //每次发送的字节长 + cliCnt: number, //客户端总共发送次数 + cliPack: number; //客户端总共发包个数 + cliLen: number, //客户端总共发送字节长度 + cliBol: boolean //是否禁用按钮 +} + +let workParam: WorkParam = { + cliButtText: '测试中...', + cliColor: Color.Grey, + numArr: [], + packArr: [], + messArr: [], + cliCnt: 0, + cliPack: 0, + cliLen: 0, + cliBol: false +} +let leng: number = 0; +let packNum: number = 0; +let logSym: boolean = false; + +function print(msg: string) { + if (logSym) { + console.log(msg); + } +} + +const Sleep = (ms: number)=> { + return new Promise (resolve => setTimeout(resolve, ms)) +} + +const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + + +workerPort.onmessage = (e: MessageEvents) => { + // data:主线程发送的信息 + let data: string = e.data; + print('worker.ets onmessage'); + let dataObject: WorkerParam = JSON.parse(data); + logSym = dataObject.debug; + print('dataObject is ' + JSON.stringify(dataObject)); + // 获取P2P连接信息 + wifiManager.getP2pLinkedInfo().then((value) => { + print(`p2pinfo : ${JSON.stringify(value)}`) + }) + // 获取WLAN连接信息 + wifiManager.getLinkedInfo().then((value) => { + print(`linkinfo : ${JSON.stringify(value)}`) + }) + // 获取默认激活的数据网络 + connection.getDefaultNet().then((netHandle: connection.NetHandle) => { + // 获取netHandle对应的网络的连接信息 + connection.getConnectionProperties(netHandle, + async (error: BusinessError, connectionProperties: connection.ConnectionProperties) => { + if (error) { + console.error(`Failed to get connection properties. Code:${error.code}, message:${error.message}`); + return; + } + print("Succeeded to get connectionProperties: " + JSON.stringify(connectionProperties)); + let udp: socket.UDPSocket = socket.constructUDPSocketInstance(); + let udpextraoptions: socket.UDPExtraOptions = { + receiveBufferSize: 1000, + sendBufferSize: 1000, + reuseAddress: false, + socketTimeout: 6000, + broadcast: true + } + // 目标地址信息 + let bindAddr: socket.NetAddress = { + address: "0.0.0.0", + port: 1101 + } + // 绑定IP地址和端口 + udp.bind(bindAddr).then(() => { + print(`bind success: ${JSON.stringify(bindAddr)}`); + }).catch((err: BusinessError) => { + console.log('bind fail, err: ' + JSON.stringify(err)); + }) + udp.on("message", (data) => { + print(`udp receive: ${data}`); + }) + udp.setExtraOptions(udpextraoptions, (err: BusinessError) => { + console.log(`setExtraOptions res: ${JSON.stringify(err)}`); + }); + let arrayBuffer = new ArrayBuffer(dataObject.packageSize); + let data = new Uint8Array(arrayBuffer); + for (let k = 0; k < dataObject.cnt; k++) { + workParam.cliCnt++; + for (let j = 0; j < 101; j++) { + for (let i = 0; i < dataObject.packageSize; i++) { + data[i] = j; + if ((i === dataObject.packageSize - 1) && (j > 0) && (j < 101)) { + leng += (data.length); + } + } + if ((j > 0) && (j < 101)) { + packNum++; + workParam.cliPack++; + } + let sendOptions: socket.UDPSendOptions = { + data: arrayBuffer, + address: { + address: connectionProperties.routes[0].gateway.address, + port: 1101 + } + } + print(`udp.send: ${JSON.stringify(sendOptions)}`) + udp.send(sendOptions, (err: BusinessError) => { + if (err) { + console.log(`udp send fail: ${JSON.stringify(err)}`); + return; + } + }); + print(`===========第${k+1}次发送数据============`); + print(`第${j}次发送: data[0]为${data[0]}, data.length为${data.length}`); + print(`leng is ${leng}`); + if (j === 1) { + workParam.numArr.push(k+1); + } + if (j === 100) { + workParam.packArr.push(packNum); + workParam.messArr.push(leng); + workParam.cliLen += leng; + packNum = 0; + leng =0; + } + } + await Sleep(2000); + print('wait 2s!') + let paraStr = JSON.stringify(workParam); + workerPort.postMessage(paraStr); + } + let arrayBuffer1 = new ArrayBuffer(32); + let data1 = new Uint32Array(arrayBuffer1); + data1[0] = 199; + let sendOptions1: socket.UDPSendOptions = { + data: arrayBuffer1, + address: { + address: connectionProperties.routes[0].gateway.address, + port: 1101 + } + } + print(`udp.send: ${JSON.stringify(sendOptions1)}`); + udp.send(sendOptions1, (err: BusinessError) => { + if (err) { + console.log(`udp send fail: ${JSON.stringify(err)}`); + return; + } + }); + print(`===========发送结束信号============`); + print(`data[0]为${data1[0]}, data.length为${data1.length}, data is ${data1}`); + setTimeout(() => { + print('delay 5s!'); + workParam.cliButtText = '测试客户端'; + workParam.cliColor = Color.Blue; + workParam.cliBol = true; + udp.off("message"); + print('取消订阅UDPSocket连接的接收消息事件!') + // worker线程向主线程发送信息 + let paraStr = JSON.stringify(workParam); + workerPort.postMessage(paraStr); + }, 5000) + }) + }); +} + + +workerPort.onmessageerror = (e: MessageEvents) => { +} + +workerPort.onerror = (e: ErrorEvent) => { +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/module.json5 b/function/communication/wifi/p2ptest/entry/src/main/module.json5 new file mode 100644 index 000000000..09dfe2093 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/module.json5 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.GET_WIFI_INFO" + }, + { + "name": "ohos.permission.GET_WIFI_CONFIG" + }, + { + "name": "ohos.permission.GET_WIFI_LOCAL_MAC" + }, + { + "name": "ohos.permission.MANAGE_WIFI_CONNECTION" + }, + { + "name": "ohos.permission.SET_WIFI_INFO" + }, + { + "name": "ohos.permission.INTERNET" + }, + { + "name": "ohos.permission.GET_WIFI_PEERS_MAC" + }, + { + "name": "ohos.permission.GET_NETWORK_INFO" + } + ] + } +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/color.json b/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/color.json new file mode 100644 index 000000000..9b2c42557 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/color.json @@ -0,0 +1,237 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + }, + { + "name": "white", + "value": "#FFFFFF" + }, + { + "name": "bottom_title_divider", + "value": "#99838388" + }, + { + "name": "tab_bar_divider", + "value": "#33182431" + }, + { + "name": "font_color_shallow", + "value": "#182431" + }, + { + "name": "font_color_dark", + "value": "#000000" + }, + { + "name": "font_color_red", + "value": "#FFD22C2C" + }, + { + "name": "tab_bar_select", + "value": "#007DFF" + }, + { + "name": "tab_bar_unselect", + "value": "#66182431" + }, + { + "name": "background_shallow_grey", + "value": "#F1F3F5" + }, + { + "name": "background_dark", + "value": "#FF000000" + }, + { + "name": "background_grey", + "value": "#0d000000" + }, + { + "name": "background_orange", + "value": "#E6A23C" + }, + { + "name": "background_pink", + "value": "#F56C6C" + }, + { + "name": "background_blue", + "value": "#409EFF" + }, + { + "name": "background_green", + "value": "#67C23A" + }, + { + "name": "pop_up_background", + "value": "#0D182431" + }, + // Button + { + "name": "button_custom_color", + "value": "#80FF7500" + }, + { + "name": "button_default_bg_color", + "value": "#007DFF" + }, + // Divider + { + "name": "divider_block_color", + "value": "#1A838388" + }, + // Interpolation Calculation + { + "name": "curve_normal", + "value": "#3F56EA" + }, + { + "name": "curve_bezier", + "value": "#00BFC9" + }, + { + "name": "curve_spring", + "value": "#BCD600" + }, + { + "name": "curve_init", + "value": "#E40078" + }, + { + "name": "curve_steps", + "value": "#FF7500" + }, + // Radio + { + "name": "radio_response_region_color", + "value": "#66ffc0cb" + }, + // Select + { + "name": "select_option_bg_color", + "value": "#33007DFF" + }, + { + "name": "select_option_font_color", + "value": "#FF007DFF" + }, + // Toggle + { + "name": "toggle_selected_color", + "value": "#4D00BFC9" + }, + //Display + { + "name": "background_light_gray", + "value": "#f1f3f5" + }, + { + "name": "sub_title_color", + "value": "#182431" + }, + { + "name": "title_colorone", + "value": "#0A59F7" + }, + { + "name": "title_colortwo", + "value": "#000000" + }, + //辅助ScrollBarSample + { + "name": "scrollbar_background_color", + "value": "#ededed" + }, + { + "name": "contentArea_background_color", + "value": "#C0C0C0" + }, + // Interaction + { + "name": "normal_bg_color", + "value": "#0A59F7" + }, + { + "name": "btn_border_color", + "value": "#33000000" + }, + { + "name": "3D_background_color", + "value": "#F9BC64" + }, + { + "name": "3D_top_left_color", + "value": "#FED599" + }, + { + "name": "3D_right_buttom_color", + "value": "#D69942" + }, + { + "name": "btn_one_color", + "value": "#FFC0CB" + }, + { + "name": "btn_two_color", + "value": "#87CEFA" + }, + { + "name": "btn_three_color", + "value": "#90EE90" + }, + { + "name": "btn_onFocus_color", + "value": "#FF0000" + }, + { + "name": "focus_on_background", + "value": "#007DFE" + }, + { + "name": "COLOR_80000000", + "value": "#80000000" + }, + { + "name": "COLOR_FFFFFF", + "value": "#FFFFFF" + }, + { + "name": "COLOR_8C9BA2", + "value": "#8C9BA2" + }, + { + "name": "COLOR_99FFFFFF", + "value": "#99ffffff" + }, + { + "name": "canvas_background", + "value": "#ffff00" + }, + { + "name": "canvas_normal_button_bg", + "value": "#317aff" + }, + { + "name": "canvas_clear_button_bg", + "value": "#ffff7300" + }, + { + "name": "canvas_bg_color", + "value": "#00ffff" + }, + { + "name": "scroll_to_button_color", + "value": "#ff55c6f5" + }, + { + "name": "scroll_item_color", + "value": "#ff2a78db" + }, + { + "name": "scroll_grid_item_color", + "value": "#F9CF93" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/string.json b/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/string.json new file mode 100644 index 000000000..acc74314d --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/resources/base/element/string.json @@ -0,0 +1,28 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "wifiP2P应用" + }, + { + "name": "wifiP2P_client", + "value": "客户端" + }, + { + "name": "wifiP2P_server", + "value": "服务端" + }, + { + "name": "title_text", + "value": "wifiP2P测试" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/base/media/icon.png b/function/communication/wifi/p2ptest/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/base/media/startIcon.png b/function/communication/wifi/p2ptest/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..366f76459ffd4494ec40d0ddd5c59385b9c5da11 GIT binary patch literal 4351 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 literal 0 HcmV?d00001 diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/base/profile/main_pages.json b/function/communication/wifi/p2ptest/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 000000000..1898d94f5 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/en_US/element/string.json b/function/communication/wifi/p2ptest/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 000000000..acc74314d --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,28 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "wifiP2P应用" + }, + { + "name": "wifiP2P_client", + "value": "客户端" + }, + { + "name": "wifiP2P_server", + "value": "服务端" + }, + { + "name": "title_text", + "value": "wifiP2P测试" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/main/resources/zh_CN/element/string.json b/function/communication/wifi/p2ptest/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 000000000..acc74314d --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,28 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "wifiP2P应用" + }, + { + "name": "wifiP2P_client", + "value": "客户端" + }, + { + "name": "wifiP2P_server", + "value": "服务端" + }, + { + "name": "title_text", + "value": "wifiP2P测试" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/mock/mock-config.json5 b/function/communication/wifi/p2ptest/entry/src/mock/mock-config.json5 new file mode 100644 index 000000000..02a864fc9 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/mock/mock-config.json5 @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/Ability.test.ets b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 000000000..e5a54aeb2 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/List.test.ets b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 000000000..cd611eb73 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/TestAbility.ets b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 000000000..b4c21f7df --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export default class TestAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments(); + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/pages/Index.ets b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 000000000..80ae217ce --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets new file mode 100644 index 000000000..d8cf0ef3e --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 hilog from '@ohos.hilog'; +import { BusinessError } from '@ohos.base'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import Want from '@ohos.app.ability.Want'; +import resourceManager from '@ohos.resourceManager'; +import util from '@ohos.util'; + +let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; +let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; +let jsonPath: string = 'mock/mock-config.json'; +let tag: string = 'testTag'; + +async function onAbilityCreateCallback(data: UIAbility) { + hilog.info(0x0000, 'testTag', 'onAbilityCreateCallback, data: ${}', JSON.stringify(data)); +} + +async function addAbilityMonitorCallback(err: BusinessError) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare'); + } + + async onRun() { + let tag = 'testTag'; + hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + let moduleName = abilityDelegatorArguments.parameters['-m']; + let context = abilityDelegator.getAppContext().getApplicationContext().createModuleContext(moduleName); + let mResourceManager = context.resourceManager; + await checkMock(abilityDelegator, mResourceManager); + const bundleName = abilityDelegatorArguments.bundleName; + const testAbilityName: string = 'TestAbility'; + let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + moduleName: moduleName + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + const want: Want = { + bundleName: bundleName, + abilityName: testAbilityName, + moduleName: moduleName + }; + abilityDelegator.startAbility(want, (err: BusinessError, data: void) => { + hilog.info(0x0000, tag, 'startAbility : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, tag, 'startAbility : data : %{public}s', JSON.stringify(data) ?? ''); + }) + hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} + +async function checkMock(abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator, resourceManager: resourceManager.ResourceManager) { + let rawFile: Uint8Array; + try { + rawFile = resourceManager.getRawFileContentSync(jsonPath); + hilog.info(0x0000, tag, 'MockList file exists'); + let mockStr: string = util.TextDecoder.create("utf-8", { ignoreBOM: true }).decodeWithStream(rawFile); + let mockMap: Record = getMockList(mockStr); + try { + abilityDelegator.setMockList(mockMap) + } catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + hilog.error(0x0000, tag, `abilityDelegator.setMockList failed, error code: ${code}, message: ${message}.`); + } + } catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + hilog.error(0x0000, tag, `ResourceManager:callback getRawFileContent failed, error code: ${code}, message: ${message}.`); + } +} + +function getMockList(jsonStr: string) { + let jsonObj: Record = JSON.parse(jsonStr); + let map: Map = new Map(Object.entries(jsonObj)); + let mockList: Record = {}; + map.forEach((value: object, key: string) => { + let realValue: string = value['source'].toString(); + mockList[key] = realValue; + }); + hilog.info(0x0000, tag, '%{public}s', 'mock-json value:' + JSON.stringify(mockList) ?? ''); + return mockList; +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/module.json5 b/function/communication/wifi/p2ptest/entry/src/ohosTest/module.json5 new file mode 100644 index 000000000..a7a10fedd --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/module.json5 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/color.json b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 000000000..3c712962d --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/string.json b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 000000000..65d8fa5a7 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/media/icon.png b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 diff --git a/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/profile/test_pages.json b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 000000000..b7e7343ca --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/function/communication/wifi/p2ptest/entry/src/test/List.test.ets b/function/communication/wifi/p2ptest/entry/src/test/List.test.ets new file mode 100644 index 000000000..907ed5b1e --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/entry/src/test/LocalUnit.test.ets b/function/communication/wifi/p2ptest/entry/src/test/LocalUnit.test.ets new file mode 100644 index 000000000..5f657c698 --- /dev/null +++ b/function/communication/wifi/p2ptest/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest',() => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file -- Gitee From ee46bb652f55d7a0dcf63a179c5bb5d6dcf3c321 Mon Sep 17 00:00:00 2001 From: wangshi Date: Thu, 23 Jan 2025 16:39:24 +0800 Subject: [PATCH 3/4] add p2p app Signed-off-by: wangshi --- .../communication/wifi/p2ptest/.gitignore | 11 ++ function/communication/wifi/p2ptest/README.md | 60 +++++++++++ .../wifi/p2ptest/build-profile.json5 | 64 ++++++++++++ .../communication/wifi/p2ptest/doc/README.md | 95 ++++++++++++++++++ ...3\345\273\272\345\267\245\347\250\213.png" | Bin 0 -> 36511 bytes ...4\347\224\250\351\241\265\351\235\242.png" | Bin 0 -> 24456 bytes ...1\347\253\257\346\265\201\347\250\213.png" | Bin 0 -> 80603 bytes .../wifi/p2ptest/hvigor/hvigor-config.json5 | 37 +++++++ .../wifi/p2ptest/hvigor/hvigor-wrapper.js | 16 +++ .../communication/wifi/p2ptest/hvigorfile.ts | 21 ++++ function/communication/wifi/p2ptest/hvigorw | 69 +++++++++++++ .../communication/wifi/p2ptest/hvigorw.bat | 69 +++++++++++++ .../wifi/p2ptest/oh-package.json5 | 29 ++++++ 13 files changed, 471 insertions(+) create mode 100644 function/communication/wifi/p2ptest/.gitignore create mode 100644 function/communication/wifi/p2ptest/README.md create mode 100644 function/communication/wifi/p2ptest/build-profile.json5 create mode 100644 function/communication/wifi/p2ptest/doc/README.md create mode 100644 "function/communication/wifi/p2ptest/doc/image/\345\210\233\345\273\272\345\267\245\347\250\213.png" create mode 100644 "function/communication/wifi/p2ptest/doc/image/\345\272\224\347\224\250\351\241\265\351\235\242.png" create mode 100644 "function/communication/wifi/p2ptest/doc/image/\346\234\215\345\212\241\347\253\257\346\265\201\347\250\213.png" create mode 100644 function/communication/wifi/p2ptest/hvigor/hvigor-config.json5 create mode 100644 function/communication/wifi/p2ptest/hvigor/hvigor-wrapper.js create mode 100644 function/communication/wifi/p2ptest/hvigorfile.ts create mode 100644 function/communication/wifi/p2ptest/hvigorw create mode 100644 function/communication/wifi/p2ptest/hvigorw.bat create mode 100644 function/communication/wifi/p2ptest/oh-package.json5 diff --git a/function/communication/wifi/p2ptest/.gitignore b/function/communication/wifi/p2ptest/.gitignore new file mode 100644 index 000000000..fbabf7710 --- /dev/null +++ b/function/communication/wifi/p2ptest/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/README.md b/function/communication/wifi/p2ptest/README.md new file mode 100644 index 000000000..9313d15d8 --- /dev/null +++ b/function/communication/wifi/p2ptest/README.md @@ -0,0 +1,60 @@ +WiFi P2P应用开发案例 + +应用开发 +本应用使用的 DevEcoStudio 构建版本是 4.1.0.400,构建于 2024 年 4 月 9 日,API 版本是 11。 + +通过 DevEcoStudio 创建项目“File->New->Create Project”创建一个工程。 + +image-20240918143321233.png + +工程创建完毕后,在 entry\src\main\ets 创建 wifiP2P 相关目录,并且 entry\build-profile.json5 中配置 worker。 + +ets +├─ workers +│ └─ Worker.ets +├─ pages +│ └─ Index.ets +└─ entryability + └─ EntryAbility.ets +​ +界面入口为 Index.ets,此处也为 wifiP2P 测试页面。 + +image-20241107104059577.png + +客户端界面可配置传输次数和数据长度,每次传输包含 101 个数据包,每个包中的元素范围从 0 至 100。例如,第 1 个数据包中所有元素均为 0,其长度依据应用设定。依此类推,客户端在每次回调中统计元素值为 1 至 100 的数据包数量和总长度,再通过发送首个元素值为 199 的包来标志传输结束。 + +服务端接收数据流程如下图所示。 + +image-20241107163922918.png + + +需要注意的是,因为客户端在主线程发送数据会存在 appfreeze 的问题,所以需要让客户端在与主线程并行的 worker 线程中发送数据,具体可参考 @ohos.worker (启动一个 Worker) (openharmony.cn)。 + +应用使用 +准备 +两块 dayu200 开发板 +在使用前确保两块开发板的 wifi 是开启状态 +安装应用程序:hdc install xxx.hap +关于两块开发板所用镜像适配情况: 4.1.1Release(OpenHarmony 4.1.7.8)版本和 5.0 Beta1(OpenHarmony 5.0.0.25)版本上应用可以正常运行,但在 5.0.0Release(OpenHarmony 5.0.0.71)版本上服务端无法正常显示收到数据。 +使用 +在两块开发板上安装此应用; +一台开发板选择客户端,一台选服务端(点击顶部文字”蓝牙 Socket 测试“可变换背景颜色,颜色为白色时,不打印日志,为粉色时打印日志); +服务端页面点击“测试服务端”按钮,客户端开发板进入设置-WLAN 页面,待搜索到名为“ANOV”的 wifi,使用密码“11223344”进行连接。 +客户端开发板连接成功后,打开应用进入客户端页面,选择测试次数和长度,再点击“测试客户端”按钮。 +客户端页面显示每次发包次数及包长,并在底部显示共测试次数、共发包个数和共发送长度,服务端页面会显示每次收包个数、包长、用时及速度,并在底部显示共测试次数、共收到字节、总计时以及平均速度。 +测试结果:本测试结果为在两种镜像下测试次数为 100 情况下的平均速度,具体结果如下:| +4.1.1Release 版本(OpenHarmony 4.1.7.8) 5.0 Beta 版本(OpenHarmony 5.0.0.25) +包长为 10 字节时的平均速度(单位:KB/s) 7 6 +包长为 1024 字节时的平均速度(单位:KB/s) 450 487 +包长为 4096 字节时的平均速度(单位:KB/s) 762 674 +包长为 10 字节时的总收包个数(单位:个) 1000 1000 +包长为 1024 字节时的总收包个数(单位:个) 9996 9988 +包长为 4096 字节时的总收包个数(单位:个) 9946 9976 +从表格中可以看出,长度越大,传输速率越大,其原因可能是:每次回调使用的时间相差不大,但由于长度相差较多,长度间的差距远大于时间的差距,故包长越大,传输速率越大。需要注意的是,包长过长可能会导致数据发送失败。 + +常见问题及解决办法 +常见问题:点击“测试服务端”按钮后,客户端开发板无法扫描到“ANOV” + +可能原因:服务端开发板 WLAN 未打开 + +解决办法:进入设置-WLAN,打开 WLAN 状态,切掉 wifiP2P 应用后台并重新进入,再点击“测试服务端”按钮 \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/build-profile.json5 b/function/communication/wifi/p2ptest/build-profile.json5 new file mode 100644 index 000000000..b4a119827 --- /dev/null +++ b/function/communication/wifi/p2ptest/build-profile.json5 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:/Users/zxj/.ohos/config/openharmony/default_wifiP2P_tXP99yHzFetlYk5drXx3ewjVaI5sWmWhG7r5K_yGdvg=.cer", + "storePassword": "0000001BAC26F26740CCDCC817A3B20042DA6F7260A64BBE97CE4F0CD0FCB17F002A6D38EDBB38D378E06E", + "keyAlias": "debugKey", + "keyPassword": "0000001B5C96FD7D8D344713AAA81450C652313FCDBE2FB2A2D8155844CC1E9FD4441F92231B258C29D287", + "profile": "C:/Users/zxj/.ohos/config/openharmony/default_wifiP2P_tXP99yHzFetlYk5drXx3ewjVaI5sWmWhG7r5K_yGdvg=.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:/Users/zxj/.ohos/config/openharmony/default_wifiP2P_tXP99yHzFetlYk5drXx3ewjVaI5sWmWhG7r5K_yGdvg=.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": 11, + "compatibleSdkVersion": 11, + "runtimeOS": "OpenHarmony", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/doc/README.md b/function/communication/wifi/p2ptest/doc/README.md new file mode 100644 index 000000000..fe9ccd929 --- /dev/null +++ b/function/communication/wifi/p2ptest/doc/README.md @@ -0,0 +1,95 @@ + +# README + +## 应用开发 + +本应用使用的DevEcoStudio构建版本是4.1.0.400,构建于 2024年4月9日,API版本是11。 + +1. 通过DevEcoStudio创建项目“File->New->Create Project”创建一个工程。 + + ![image-创建工程](./image/创建工程.png) + +2. 工程创建完毕后,在entry\src\main\ets创建wifiP2P相关目录,并且entry\build-profile.json5中配置worker。 + + ``` + ets + ├─ workers + │ └─ Worker.ets + ├─ pages + │ └─ Index.ets + └─ entryability + └─ EntryAbility.ets + ``` + +3. 界面入口为Index.ets,此处也为wifiP2P测试界把面。 + + ![image-应用页面](./image/应用页面.png) + + 客户端界面可配置传输次数和数据长度,每次传输包含101个数据包,每个包中的元素范围从0至100。例如,第1个数据包中所有元素均为0,其长度依据应用设定。依此类推,客户端在每次回调中统计元素值为1至100的数据包数量和总长度,再通过发送含元素值为199的包来标志传输结束。 + + 服务端接收的数据流程如下图所示。 + + ![image-服务端流程](./image/服务端流程.png) + $$ + 每次收包个数 = 每次回调中内存包含1到100累计回调次数(单位:个) + $$ + + $$ + 每次收包长度 = 每次回调中内存包含1到100累计数据长度(单位: 字节) + $$ + + $$ + 每次收包用时 = 每次收包结束时间(收完元素100的时间) - 每次收包开始时间(收完元素0的时间)(单位: ms) + $$ + + $$ + 每次传输速度 = 每次收包长度 * 1000 / (每次收包用时 *1024)(单位:KB/s) + $$ + + $$ + 平均速度 = 共收到字节 * 1000 / (总计时 * 1024)(单位:KB/s) + $$ + + **需要注意的是,*因为客户端在主线程发送数据会存在appfreeze的问题,所以需要让客户端在与主线程并行的worker线程中发送数据,具体可参考[@ohos.worker (启动一个Worker) (openharmony.cn)](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/reference/apis-arkts/js-apis-worker.md)*。** + +## 应用使用 + +### 准备 + +- 两块dayu200开发板 +- 在使用前确保两块开发板的**wifi是开启状态** +- 安装应用程序:hdc install xxx.hap +- 关于两块开发板所用镜像适配情况: 4.1.1Release(OpenHarmony 4.1.7.8)版本和5.0 Beta1(OpenHarmony 5.0.0.25)版本上应用可以正常运行,但在5.0.0Release(OpenHarmony 5.0.0.71)版本上服务端无法正常显示收到数据。 + +### 使用 + +1. 在两块开发板上安装此应用; + +2. 一台开发板选择客户端,一台选服务端(点击顶部文字”蓝牙Socket测试“可变换背景颜色,颜色为白色时,不打印日志,为粉色时打印日志); + +3. 服务端页面点击“测试服务端”按钮,客户端开发板进入设置-WLAN页面,待搜索到名为“ANOV”的wifi,使用密码“11223344”进行连接。 + +4. 客户端开发板连接成功后,打开应用进入客户端页面,选择测试次数和长度,再点击“测试客户端”按钮。 + +5. 客户端页面显示每次发包次数及包长,并在底部显示共测试次数、共发包个数和共发送长度,服务端页面会显示每次收包个数、包长、用时及速度,并在底部显示共测试次数、共收到字节、总计时以及平均速度。 + +6. 测试结果:本测试结果为在两种镜像下测试次数为100情况下的平均速度,具体结果如下: + + | | 4.1.1Release版本(OpenHarmony 4.1.7.8) | 5.0 Beta版本(OpenHarmony 5.0.0.25) | + | ---------------------------------------- | --------------------------------------- | ------------------------------------ | + | 包长为10字节时的平均速度(单位:KB/s) | 7 | 6 | + | 包长为1024字节时的平均速度(单位:KB/s) | 450 | 487 | + | 包长为4096字节时的平均速度(单位:KB/s) | 762 | 674 | + | 包长为10字节时的总收包个数(单位:个) | 1000 | 1000 | + | 包长为1024字节时的总收包个数(单位:个) | 9996 | 9988 | + | 包长为4096字节时的总收包个数(单位:个) | 9946 | 9976 | + +​ 从表格中可以看出,长度越大,传输速率越大,其原因可能是:每次回调使用的时间相差不大,但由于长度相差较多,长度间的差距远大于时间的差距,故包长越大,传输速率越大。需要注意的是,包长过长可能会导致数据发送失败。 + +### 常见问题及解决办法 + +常见问题:点击“测试服务端”按钮后,客户端开发板无法扫描到“ANOV” + +可能原因:服务端开发板WLAN未打开 + +解决办法:进入设置-WLAN,打开WLAN状态,切掉wifiP2P应用后台并重新进入,再点击“测试服务端”按钮 \ No newline at end of file diff --git "a/function/communication/wifi/p2ptest/doc/image/\345\210\233\345\273\272\345\267\245\347\250\213.png" "b/function/communication/wifi/p2ptest/doc/image/\345\210\233\345\273\272\345\267\245\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..b1de65e28d21256a8cb4128831b2d5896411a803 GIT binary patch literal 36511 zcmdqJ1yog0+c1a;3J8jTl!y}2-KBsajkL6MUHXFLMFDA$E&-8_3(|49bfSU15hQX0%!7#Pnmq$OUfe*CsE?XHtFmb`s-=cauG+q12kKRh>lgeiGhI>80{)ghG@>REl33}3L(}$7)CadkKR7xg9*LGqH1Y%qkffo#0dK?6+T+pz&PJMXbYz^he#&? zpfH~K7{FYvZ{jQ8qCn%V^Y4vVmc7l-=PLuOc$k>jRA0_8eZnr(aqv3Fxj|=xuq4UJ z2d+-K$8o$bqp8FKM)7cYdYPf^^!#Uc!TTPFN+ES%Ffr_%h&joVl~Oc!5+WZV7noV` zQ`6O*HwlL(_WWoYwm;DF0p@ZWeBeOO>`JYcPXQBB%V%bGHNK0h0JU-dxS(O({JJ^z z)9=eqqvBtF8@#c58*eceN2GIBNumQa=i6r0cY99v@+}s-PW`t3m7buFq^Z+%OM41R z>l;3`aKTyl)iSdCbzL>kYbb7EU^H0&LZML3hzsm+SmCC#yRB`JXzaSoS-3SNsb( z!mg7Q8OHHLj-Sskzli%ctt()X*~ql}xF2@K8dbEEziu|vEH!+28udFRpL5Gs9G&%T z7Fn`@{QjLP;wp}nu>8uS-M!K$gX=s-P|!;y>OeDa{H!ai;`{e&;{IH%CmcOT^A?qf zqNhfE2?S>l8<%PXYNmKJu?4*~D*7X|5`$H;qG|lQqoOh-0Lf7K~1{R(Ph*PAXnRW?o3;K-H)#Df1E~f#{_V*0ZPfv)}>`N{9CHp%((6Q zuZ&_wK41L(iEQrWO_OjLBim<&x6dG<2h4R9(!~g$ z9a#}%yf+&gL%7G_vkakjTl>B0H3R16&OA*jX4c}-8zmlIf!|qcV7f`Qi)t2Z#d^jcg9g8AJ_^|!^jqdnt$VFOcefe}f zx4GtRdc!w+3r#;^d)TAHBeo1(vI3Jl?*rTI&H{Bs1t*st>t%90vY&^;JpNRujN*MvfH4II`c z)|?*y82lU|bw__jnN5i4(E`ENw<-4wd8~-Yq!_k3Xk}4i;onZZCg_ol-j-Sq!D253E99DH0u2O4^8c4lrPG-I`FKT&GID6C#t7mSB|42%%dX|*he$~rc zd38Z7MI=#2{Fs^$Ds<$-Ef#<}JluR?Hd6?%-~Z+rlaZt$uVSaPX{+}Tb}~3xufMKI z!*5E8g3NwyU1^+~JDo*3@bkUw7+_bI24w5G7fd`W>P4!3f9m?iXLa*?IgQEF6dQ)C zRG-9w$CTFWtRCCje)z(vFk$m&FLTD8Oj)TWLV^se>=v$gr>**#``jas5vojbS>0zNf93+Dd#6Ee@U6c{~K;46shHU5MgeC0Sw zZ6Vk)p3CDLCR%7M@i#xZc9)KGI(|QJl3#dR0Hc`K+)eW=@CAjxK36yyR+E*+YkpH(fUUH~)*v`_H%j}fiR{hf+c9e4+ z!t5x#QhsOSbklZo;$l>GJrlD}6a^{T@^b0#3)JJK>+!J#a&S8fpHjyNm5=ByLt`#6 zB2p*p8!$DJb3sRzp+qYe(X&0O<#fSW=7Ge*jfvAPD!igYWxPe?XoZGLT&vu^{)Y>6 zC4-~dR*FSo-Z@HFZ(|yn*y#eatg(rQYeFPiLrkF^>Az^fCn-t7 zRBQQ63tg;To5v%+n0eJ^b3qrOQmLnfLrjNBgsv~-!x)K+$pn$i@;qdu8=;DtPf8)n z2pX+ro9OxjNfVo+x0O;U!VEGpDs(IjFZBym?lni4h0)f%kElE*p_(Cwg{feEtGjbH z%d@bqSb?lT$XW3z@6HzvP(p3~q)f*EO7yp>hHdV5gxmDsK{ynyKKF@kMyzjb=~-Nv zS^h<}!qx2s#X|EAhx2CFmjVu#*)HFBE)h{-2w@VSR_PX#P+qjMjB=;JQPfEtQ(djN zifXDNYVTZIo~c&rJN3M@b%(kDNF#z|&Ppdsgl+kHdAB_(IVusBixb&-IJq=o+@Jf; zKPp=E#0bAo)Rir(x4gicDd->o6ulm(`Yfm;-^ubzF*PqfXY?eYWa{k)^KqI7y1$azdy2v7FBMHiT@}^E{VpcJ`q}0Ah4vRBct8if z$qhcpxy$nTjo^jZV83dBE`MWL)H;EY?}|-o*{=z^77;`>U{ty1%9S2Sd@*a(`z*p< zwe+Y7M4fxtdx<4shSnl8FP$HRU((YPpku*OILh$SXyRlRq?JF{nfB!%@&5DPa(AgL z9=uwItO@&SduLrvtcM9lE6x^%XFZJmZI#bj(&CQv*zaw2#ZB>Yq^x$qs*>d?=c1kH z*1*HlGZ)X5KW1S(ipy(TwG#$URLV*q#p>~g#93P3xAyRMmm(OKifP!wD96&``bmB9 z)9EN{a(J<0Y%HqxI}w{#^Zw4(aE_`Ackuw;D`zJ!w{yZ|_*LVQ&WL&A#q}o=88#Eh z^9G>PvYKblAW4WM3Vq6&X~>lWYM#B7Ol;iogPdWtup+NM8Ru2adgAMV_?APlsWqN^ z5nA&cs|c?I76-};k4zn4v2C7cwVx0vD*A_0R9+bI+pEHi1xuXVVwWqV#=>#v_!$n;e z&pYCs!pC6OT)H^UC=e0!J6Y5qK`aS?tVg|_Ld||}-7kJdL|cYHO5LBW zRVOOv&GE##{pm-LiIiy*mez@g>KJ!tjWAbf!)pAkraxfyv31%U0>#2V&MK0kjA$*5 zwNg3{LwvZv#7TR5QHJN|rf8qH2Hvj3&LE1Ro zr!@KExR5w?lKWBj9)rsj-?Sc`FuWCpAWf7l%Vpu*ut|rbutenlu)^h_y7y`>F$s!d z4rWI1bbrCvS$VCJ@C}RApM)uJS}RtK4>PuTlCmk2&ueaIUJg<-_f$|c-oSYEDxxS- zA}^wsIcb2$8Bs{m2KlsHw&8F-DN=c-{hBTKCaqH`k>8J$ehU)%v#j(Ms@1Q@tv%ly zd01H^Z>0Z~lz=|V@`6J*!)h}GQ69;DPXX^+kr&>BZ(~WmJXR>q_mdVC75R@b6mr&QN`hzKJ9RML+uwQ(N{Mij*-SKNQtEclf!(%L z1v|-6ZHZCpTkJ(B+7;DTl1r?r_%#U+fYsLaJ{zK)a$=u3G?KmcYjev!m5lt_7#Kd) zN)Xr_oe^?qE$D*VUHX3bY?-7PjCb`91nTklXh(&QKg8U-KL-c;-??~OxyxS zS5S-Hx^P;TU%CJ1dg~VrmwJTRqFlDvXWpv{F`!9vkxuS+Y4B|?A%1h1w(227uyA^L z{)0WvNy=?{iq+D&l`Tg06xkq(3gN{3M_)J>qPD6&e_P7qWRF42!ppAYvg+Lr3b&v3 zMhdJR?CFl-n9yhq#dJDblP@C%x~@2tu!XUaDzIUW(6?} zou431o&j3c`jp}3ws;5}g@YiuVYoxPGIXM^&IRhIMniBNwChPt^MK|VF@rQ{Fsi>+ z0Po`ea^u@Ey!E-swtJX^Eh2V-HUGzti)n1&0KDsgTsvwGRR4=j#JV1E4I2vS0ZfUbkcqu>5Pkk!73dPj+maXD1UH_c+pV%L-h-7TYG0*#f64+iDrZ$ z36CHB-lOwTKXxLi+Mn!(nf2~BFd8Ht-@o&YY)2p;`f4;hinU@}VSu+M!JxF*9?tkNpC6mk()Nmb|OW!5vz6ofz3snba$ITRg5%5v<*0DuYe0 z#WdrX_*J3v-ZnqP1MW%P=jE8t`|yLX&>u;$V_prvDLCh)&i#q*rlB`i@YaVUkhZa~ z;0PQfOYI-KtAvF%P9wvb=eA{pt;=I?76Tgb&_}bR7AhBnb68X9x-$A%laWN1Ct2=H zB*2?&IG>9vgCBc*X&Rn!k;NJivFm;m8I|#POwue@Uj72zU@1KDxTe)&57n%)0PlJ5 z4*DKu6W(gZa)3?MQeJnoLHEs~lk!Si!L48Z7PCdy$`h)$D7#1KYM)*Dg)q{5?IWAGKaO8pMP+rFw`%vlwdTWRX8p>y;Al?w zX%Q2F@-%nSH#+_89?<0Y8CeWDX=CHX&o80+FqmS$Zaq{?Y^37&`i=Y^>Z^fdvFc~Z=8xntsN%LpuongMN5X}MQWmA=i1Cu;v zi`QtWsM{${(4RlYEt7AS`LlcwS;bQnK{)hhWD7fGJ+G}FX}%YW$IFGy9x2m0w}hvE zWJqTwS-f|#Sf-dwaTH1$f&M<Efa& zC+8$(w(Ng(m>sK*XRDN7hc>j&!xsx!3Wpt_EoKi1zDj?SbiDfU1}5S@`scVAPxxTf zEEVeHe444@^%k{iaX$t>kNgmuKg=ko$s~wVB=@6UwYu(O3s&s+Lwk8aqrP*9d&|2oqT6K#_CsaJ2`$?m2PGx88XrZL^4Bx?KS=p~;ac~| zUcEdfkHHr!Be%KSiM8AxeR3E-B)Q~<=gcy$loRbH_*(6Y3Pm?ua9haiVbUg?kQR3M z-JB%BN~6F-^nJ~IhlNe~A#Z}AQ@@M8qg=lzWz35nOq5vim1QU@!eBeb%3m??cx1In zbGoJyGS&ZKv1Y-2{+MXK-c70PKDj}d${R@*W)FjY_wCB*I%eOM?d^I^PkK>aUQyN~ z!$TTg)?cmd@r7Gt3H^1|wny^%M^C;sruL^$JRyJi9^q_Y@O{Yvj{oDCXp!;eWZpu1 z@_uFbi4a8A)B<;=@>Sv=C8hO+i7SkBu7z_L0A_hJX&AE z&4D_Em~ZYmIAj{=zGT!hmWLO6t7^v zt0?Y~-N#gbnAg#^_QKh9-KFMBYV1CJ%s)v+KDUu-`U1_>C!}31yB5BS=(SR0)`Q%@ zgX74)Q5T+Z$&!t;Tgi%(sU_OyrC1kVmhf8NZp_rCL${rWW{?*~jM7aaE^H!sHHXQY zJoFnjGwknvlzXCcq0NzORFd<@^E3<#*>H;IP6yGwd4GPWtf@_f`Qj?f#=Q+6qp z<_BuDKRl)0HMuJ#Z5rLOH}}PqLE5{MN%QCTi#`f^OTljlyAQiR-fRt3Tq;!NRT+=m zK+4_-EIdDCuVtogCnG_&cnv`()VLQ!AANEsf@)<);a|gW7Oj&4$bvMa|knk z&^PPMvZsJpE5Jw9g395kfR{TZDQVZX2>Q7WE2d--tyEmc=}5fOpG?2B(WGL{l@ zX}lb+@K(S67%mSNozB)jEI$)P74MIU-Jc*MO5yvcf|b@4eBEiL0`p)CXuX;j@78_s zCnL|oH^)z`(imZvoqv*?vX9vi-yqG#?9t| z_AE-YBo{sI|FrMh@9*8ykha+k(~Stubp7z^^j>&#U-=D!>5aBb&Zjk@)!Bk>tEvh~ zhA%0t9N$LcuK~W-<#p?c=W-xpG+K^-)IC#i?>?OXrj*gjOydl^Yvo{xeOk zn>162o|intUci*J_n?sJRJ-dlCZQR6a{g(E>TJ#W66?&seG)3)p{qxI6hvYHzdj$S zS!OrISfFovmu_u6y$B`apLjpQ9Y=vlY+?*@u`NfIf*0#Rr`j}EGU%P_1#(@~TE5Hs zl~s3)eALe0DYl|mk942Qsz1@2>9`u#qO!S9C0E{_5mMN#ox?%yJ`LTQRHErMTW4LB zmo<#^dj@%-bh4=z*}!Cm{jPhm4mEvH>prWw+=P?s;CAz=WqEt`UoILp9LQ#T47IJU zvy}7eF&$ZgM?`VOJuTMMlzegKblILBPT7x(9y5*@^NRUG#n0j zs+TExJVb%1;knuRmqhodGP>}y37p94)FS9CXRihxAb&xQ)!!8Ow|T!$dnUSFTv8%R zeyN1D3n++-Wf0O=wJn7yQnyNfWB`s z>2nkd=ccj`E8_K+xMvmKJ$$(TkiJQkb0V>+Pa*$pxTetIdfkk+newU^QG_7}jAyIJ z@68coD0(oi6K7axLd#4U?xj!2TbhFLBprcR4uze)Im}FalR%QJt9!LKbhS@eKYJCY zf9a5?zP_}f1}jH8#H=?CrE=%TMu(8=RpplG&`DSp$UN!W9>S(lk6Emq*izAVAIi|J zlcw{<7t^S-(8>2^W!A4y%^NAqFDl9}x?1UoXz%KZWlb7f9^puUIHHE&R5un0r&TUq z9bP#J386buYX=Mdc$7oM(@Zlkv|g&$QH~rga@ijK2%?`DsMpX^I#vxi9Zk09`~%o1 zqGWa1NIg3|m--#bsw#7BXGC-zK`YN7N?FREJGM|qSY>RN(MXMX{M{R zz6`%OBRk}6`{s5!=00Cne$i^U`fk5nbTXS*?3>rw#qo0L`3zdh7e8zA2$n}I20LH# zQ6#d36>DONL*Vq#^Qnr95(G-8b{-CF^$G=;Kyg>Ll0lSeyu-MwL5!sS(sZr zaYBF5n7YNsw{_?AR?)W5@3{^UV4molugrTqpDSLuwOho+@jacIIw}&~YjU|M*O;B^ zNehvk_t-i23r?d-8&vUnsH&q(D}}(mU(YO6>W#_VuCM;)jeBupN_-~o)>&frl=E(T zxQza6)wUJ8@CfI`<@QYRi>LTsONd!(2CU;7v4@mZbbs(*m>p$Wt`~I@w&$YmVi=^n zu)O6ZL358S?d$7wY3`-4$PX7Ov1kyVRXu~;B2Xp~_53|}Mea0tU&-Wrc=yngcLuFe z?^}h|*)LnKy@BCP31UUXZwsKB+u-!B5*MRk%Aj;2x=RUmbTi%-v`O-97lrZHQ`wl; z4@Eqo%vSn%R8jisd+CJrri*cHnvagfnayE+$1n#5#;4q68{7VAJ@9eEfzoxU0;9vP z3&=@&!Aix(MB7@`NYjFg5vwy&lR6o>-jvjhA;r~$9{Jha4i#B_UX6<#V!GM^ z%;_a!hCTP%5mGSc63$iTCihV`iM(XF&HF6#S`jxsqoI98vlWxD-vk{~2gyOTTQ3B? z91Jt)W;Gq>XWw>!uj1+JGdJf8RE-u=N)vo((4%4QX&9~GeIYw%AbRx5D3Qq$s z4%$46-064MkLoInid+)GQX6#Ui^`Cu_Ic9!nYIjUF(!{qu{_g%YUt$n;kzoMhuAHmdR35+W-I8Gq-7PXN|DvKW4tU^b0wT#*s~xH zofcG^t&hLZR4B|_&k=cY(VkwrYZGe-S& zV@DT-l1B&PNgN7qrR3uBGc=O|9tMF;XtlZOg(O3MsEIQDo!YBIAX5 zc+M)K1GZHcr5in+mfYo~>uOFqtX>EUsjHnSwO+K&w-mE`;)|`YawYC!tsHMVhk3GHzyJE~bmvnzUd94KCHiD9^A9K3_MP}#8$dj_U$>4!M$Ck~}gQ(6d? zDrFN*yJRrs*Z(r_Vzr}W;hZ;W8E=^Un63S|B_s5)yHlm0*?S|GsOXH z+xa&FS5WQ}b+jXywZ?{YVZ%blWo-kvW6AgFYJybdl$o5?mK4!pg0OQJu3q#tyTu)! z>qT10?6u3EKD9C@vYalFJ2QfYltBXc-a#kgwa`sjIIAC)vRDao68rk>9vo|`!P(0f z1(PI4nTTK)R;@;g*D_*TK(cB6{!`cZg!T3phO58<8;|96tCriORtJ*M9>dVQ+(uoR znr@e}C97FYPUPRI{g2&j5PXbkPpovu9;6(X%+ z^DQ%D=m27d6fb&3EGpmCy%dTCx{z#3#%U>n4OEn`ya+KC&L)ept$ zkIM7n<76ajK3r=c0^27Jp0g86n?d2cM>|_bJM<1N_6)y-cw}%@LaK~J?2F6u#~6gCP81G<^_i*d zZtXlDs5}|YEayPIVVC)1y|7io^ETTRJFq?R{uwb5gJXYMu`>rB z;(-xUE|e8yJg7~mF>3!V+`mv~JJRy4VS4ma)AD4KEXmGUR*W0|phnyvr0R~8Jv9X2 zuhyYq7u%&*>#)@1Q+tdZ?`xF#XFw$5i|_t+xvoktr4gN-c1SZ;B=dvPn*LS&)dCe> z`wau-es2rlI++6wj?3-;?NI+0`0woZZdKMe|1meJR--8yv9 z$GFY4bd5$OJ=2YtHXEvzz_kkcEsPbmfer4`Neol(Y6t)?I*Ej=P!)@+W=ks!W$Sng zqfY9YKH?8Q1eME5WtHKPBUY>Y&Lj$Xk5Y1MqHF?gVdw$74p6P760hTq)Yf7=Vcj0J zVbZHI{Tvy&Fap60n|>^|A?mze95dOjo^@JVis2!X9w%{*MRgYwQyWJNBTw4rn(hN3_LUoLUZ%Q{nCi)&TAN_lr&X0ueki^}rWj=*1>=}5%S7supU z-H$5L+0H}GjEq>tWYuu0q&LL`)%J`N%FbU*OJVF2S&(7i@w>$-L$rYLoIS91iz?K*5m&EXFib6OeIzK9A#{Mz7cu94|K7 zFZz-M)ZZS*6P&0*LdKUbf2|*eku-*dJwWQ|D=GaxQ6t#QyL)`+n%u?3_BGwl@tz93 zd;?j9#V)jm7ipC4?HugkGMz_S5BztPwJ*pYO%hJBfVU zTkNdAT(2)ID&i##O(8Q&=jwTMO*%k!e$kNNU~Qz^p@jG_;1dC8S7uXQZf>UmTXbC9 z`r#>~MxiDX(Q@1JM2a`iuwNteic*~v`pmh|XtYeL#{+wNdn6K>vhROD%Q8)LdxsU^ zRZ3jkN4DDe-Me?PvfX61wYzO(wqRr#fsbp$^s8@WWrIvElr$Ny1QR+g71BLL}+Wq!)@ zI?2qoD?a_n8WuSe3T2T}R#ql2od#^C+~It#Xuma89hil*ovN}wKi<9OX`Sl9eVQdM zP-yFDwJaCNJJ5L<(-lg_E0A@7b64Ef*4Dzp0&LsFf6l;=S6Qi%NFN<$4Zi*X|CK># zx*?4tYMArF&Ix4uJ?$3>6ouYtYp<6)cBln75(1om->=EER9Z?)TN{Bu7#SLFRoDN6 zBJ*=T+tBsV_e`-DXGelzs%mP|7UDq^gVw1=M~0cos~j)*TCs14G$={^Hn+4)Jnak& z42+V5P=Rf%c1lXWkUHkEMmA*LIFMdU;OK@=xB3V^0=%T{E#(&wsL9S=4&|NMv74N44c6AuA}2tFVgFfP zo)uR#dk7SIN2_aSb?N8NH+>q};1s<8AyQIO&d%sEmfOd7uURlZ-)fCcAL&*ObPE;L z>old8kMCzHlaP|;sWK2cgP5D2pC1U@LghiisGlkS^^hh%$edT4YSN{`6)MY5Pfsx^ zJ?ylIZ+iFu3HiX0kma@KhfNHO9gwtv#>U3@`1ntsK7o7!s?wH@mR6>9Vt02J2zUL} z#diDHXT^1~QgWb;bZBc}hqhk(WKz>>!`xh4a%K3v`=KQ_s;~8I))}3?ynLuXg?sJC zw22TPUv)e_=Tyl3N8D_cY{NI$Dsf*)0TRC`ji-AI5kCgHcI>5^j@x_#fFew1;90XMqIfa1H?|m?I34CghIQ*dSKOw z0J8dhXtk-SiF|tis2%Y7Ddqd6p(Ku_=RhX>Wit1AEp=mL{`lk{-vuUc@evWxk^?m( zBO?=2&q?gZY=vY8cPV{(%>q5-q&Wn<1Q?Epj^^rTS-b`I-#L(^;vBev zZPevj6oiD(g|^UL)_VH|NmbQoEx5CVd9ByI_oyRwuxgT3r<&;K$IFigfBiDxBBj7{cXt<_YHF}7f68a~ zjDexcz9qAQn})`(f0Uh!4X{Ekbp2Q7_Qko%5#@cv?|bR-jqjWMcAj zzms74DfGuaa-jXaZyD|@JuNtosOZ(+pYEr9K!pHixHdX3+>kS_M_iSA`}@h;cW?d! zyDwfCbw<)?6zRo0O%ZY}$;mPQ5j{0H=m1nSeMPNtXJkkS&i0{`I!FM0)dd<9I2HcY zp^1s4ad$pM$w*7nGcfE)ZetXE0GjAAF|i92Dt%`PSk-GQdBhVH6%`yDj2u8r_z6p6 z95*e5i*B_hDYUn?3SS;C%vj>?T=QbPQMho{fO+jmqGY=3Msa)X$Yg=oc=#UBI|a+{Y~?xTXaMhr`9`q22^O8$Z7*xQmF0m{}Ps5C>nqP`+>P&WgVWMi4C<0NC5-tPf3+B23T4>mgJGcqs$b^)B4H2Mf?kz(5# zL|8!BtaB}GFIiX=WMu_iwx*ma?+lxBF{&5D!@8gAf-Ki@qIy2C1B2=~3)}L-DGJ%$ zU0sHyAA0z&%~;6a>&urfz_rSqI->=w2Y4rCGhg^2V4JI7tH2lQ` z@Y25c`AIMDd=OaTx;9(te=ipo7Znv1ZEbB0jkr$Z$gTAZRR%Q%HEU~YU|zJeCOvA{ z&obVkyjeBj>R#bBnW_w#E@rmeD|61CJ2!$`uf=*>uSZgkat-)p+VUSvpKKBUg$}Oj z_Dt-)rBidW80z2H#QE8k%`B!Nl;yDGiZ_NW`X)TtJjGv?CAM-~w-Z7`A$!_-ZxP1^9iZ2-X|$ z^z?vV`&L0UE@iLV-@CE@7tj0|c?1UVB? z_p0dC1S;Lr7y}e4ZO(>91(2IQSu8nK8FE=!Hz+v|(K-Lze!_+#WYL{-$TGxGi) zdyN0nohb2C?uqW`eL8s_Wk8`$?Pc>L$xc+O$V!&`Swfag5eoPuy+ z)hj?xjKs*8%-zDn!Fh1J_rsf-PEe4Zz8Jpgtm}z%qGqR}5*CJo5-*-}iK5)wjxH^x z&FR&JtL@(|GMObipFVeVbW~JS)STX>Ctfl(yK{ZYW@`rN-iTUg`~#n{=F!m4OBm(T zuPC!?{CsB++Yev)%4}*9`PIwK$HzzSioTaQ17g4eOlXZ;`IfW$8Irf0O<0(oKKFDm zlfG`VO+t$CabsFq1i(RxpdA9KE70hg)&5W^%U$;s2OC??fH^IN*Q3?&W&lM}r431F z+Yn5Ib736-)85|B&7~7nm=u+aWD~wvf@^cy;5+t#V=*!LP*9hA#z;k#R#?}#Yxlv; zO&?YtSH#D)ST)~taNw^Y0&Y}wsx-le0GI*$jN*6OF|Qf91rKYVQc%E^UPjB9h>3k( zzN`dS_*v^*$I88X_kuY%S;q9(Nkfm$<&SRw6PG2CKH%hX6o1x38rnAN`T7~hQG%eL z;5K4g1b98A!L+p0=3Jyw!$e}kBV&TuMCDo+zkKj&n5o{%z11xCNMLoxuBM@;ZfR}h z$D9R7uD&{`aa|t;4jc4{`CG6Ny#fJhdK$u$w7^w-xfLu5(hxlm{)vgXhjU^9D|fK( z-o0BmIx-73G#DHE_L@dL7c&$SGc}b2(yyLRC>G!AITFWWVru+$=xM%&@YKLW^)m+G z`@TO-rb^!C@cXWwZ)EtRNZ%F*4^L56RxN)d%q%^f_$_4#U>BXdYHMJFnE8$zR|lIe z>%6F1$_lah5HsVN#|^gO@w3jze&CwY1iOucO}P@9 zqGkHWlKtMI8gw3!lh+zc_eIk1i(yIOS{;186B>FNOq>rE+0(82+;8LC#>Uweq6m>K zh4t{!qaVuo;20Kd=FHR-4Kb^FQm?7h8z~^;vE%+d7Hknn{ox@X5qj zTx@J!U}%g2)`JIOfq}w~XoB1b;Bf$Qx~{-LKEqH_*oag7$qaK;gX zFg9U2)SRbEM}r`n@;^N}GHd9}hZUTJ8 zEiTHfm-a~)VOLeTuE)|UIL>+=ar5%ZN&&OF8N=AOKSY2lmOe0UTWqdUUWr0w)^C9~ zs;a6$2Gg6=+)h+2l{5X42FDmrivQcY!`e#!qZuY?d-RP%U3|@O$LUCvbKSNKaJcBW={=pmI4dxSPXg z#}7Y_T?VJ8r*l$MXP7M#OQkLlw>LC2aG$Y;fq|R+Ru{bNpX}{B5IlMWViMr7C$=F! zwYOS;KqOP2+|$!DEMP+?b9!b5pga@{FV$`HEaNX@zcRRohllq-y^1_qIY2V~9&gea zGf^B@YW&yl>bZ~azv+C@I`}ZDm-dbE^3d}a&mRY^GT+(t&~1P#ie7Ad`g|T8ZM>Rx z&{%V@8&-CAtl0{;_e)PtNQE%$?t>64&+g1Xf53t``~Q zSYFt7a@)drDh`p=z$+ktATnvIqQEP0kbBf_Vc5R?d2nnjE;Wvfk~mvA-*zVYPk2qh z&d%@e&*FR}(+3QTTPzHFmv(mPMM2yKSI5M}6!fyk!Nm>LXUtUv2N1L3-U#cvI2*=L zvt5DwV@76{%(j)Zv^0n?7ho5FQGg?=1(7k6%I;PHjR|U=^AL zgIb-xe;YvZ)CJ^|@-{0qv(98YnxQu;LnMt;5TI4UwSLmJ_?x{5tCl-yqruy0!|r1W(=J|!AW9kGAbyfHE}V`EQ& z_r7l-tu&vJi;HVQ(Z8&WPu>yroC!0fpuW*Y>rnZm*l zn3sLlu**xYb}i{p$rl$mQBjeguOOl(YlIhXEIAp}SC<|w*FY@ZjH&8z^YP`Vevu)- z5q8;@p>%d}hJr|-Q19^P!7fM}^m~epTZ@PFzoL=J6w!gWo5%4`2qZr z8|&V~dymgJTi0(sEvqQ!{|r@e+y^cTFi${!fqRLY!1r| zUz*;^^xQRs0;Q$O_&g?9iQrKOi%vmbXP*Np9%S&o=xQ2p_tC3nK*_MY8IUbeIqIHc0%~MkWOCC(%_pSM28tkv(~$#L%2kd4vG#l@&^!X+W*5k!9G~mQK(fw+`^5iQ6F- z@C^JWb1rEs=}c&XWV-zi22yE7#qeHJZD8XMUL>#7l&UM)ODEKyVSMz@t&}1p+yoA^ zfXdW*vn$My65VGzcE>vxgyMJZobcMtBoYu}KNy;Rf@*zybo!OZ<@8cfsYs{NZuNfL zixJ}fX~(gt^vK)ZKVjd9Ii|z+m$slc41zxUe0GRi>`BuOVAa-o*=yVlF@-*JJgVW8 zq`8N`k}>h;C!2|QGq*m=#qJpBzXlxR3B|?4z34zZn<$oE7Jq+#S?Dtd{l4unq?Br; z!R7Zzu(Mb0&fi>igU2gS4#2=z1VPmQKbuGM+u#`BIla(!ApT~__pfYV*S8m^kU0sL z&Pve*vR?3Jk0QtpzWRN?-~GAM9K#Q1Z|wW`uyv~#gtqU2zB|c{jj!?WkipfE2B{KC zozyDp{7W0_EAM&)2W4)PL`}^)+OKj=lz(x%u7`$d(nJhvzcY2xEwOflR$N!z0SEfV zNy~VkQmm|7;+32&9`?gUcm)yR<(oZmlnuI#bMnvk`(z4g(6W^2!}o_U*P@Y#8@~+A zW&V~^-o8V${w_ai*u4(gj76(v;!mdg9>9)_E;-&yB-5xToJ?C&VNI#f^;){~T5=AX z(6lSX-F?;I(K6SYGo5;I@kPP598-f_A(FX7_ijo3$4yKo%uzP>O88PrRrf9(a( zN2*E6dY|zv<&NqB)yHS_1u!u@egP`jyOo%fd$QXidU$H^;<}E1a|c7t5C__XtDH1lTRK}tZt{=xqFSThFa*zvqXV*a&~RsiRXy| zZxSV$22SBdpM0*5s(PQS*3NKS3R-EXGojLX-}jQ4PqXVPNcsmQAFR z|Lf_W)vtYdU**CmcHQd(vfd|>>5=Qka>Un5H>ewE>wt1(T^Ii_*k&c9g1CC4`{afK zR^CpW5p?`x#9xo#0V;|P3g5KA8gfK${G+od^O$SmoWfARAAwXf9h=`V;`+SD*X~E~ zUu{_8l`CAK8~GGzk4a;GwJE)tfANp0nFJyYHWmL*0&+0Se;Ta+AK%^Ey*|r|!RDA< z*gdkhCReTX;N^dK_9X3^RSX`a*SKA0xvydUpYrT~moxtBgZ-0-@LwwE9=YJr{uEG| zL9c5|s8;=I>vE5o2n3~Iuop^}jB!odFRgp_Vh8iD2rd#5vXn%|jjWCjH+Ho^b`U-a*2~W7tsx?7yWL0C*w}Yc(#D z366sI{+|P{4{mc1`@areI13l5g0#T);k&sTHM2aRat1grjz@jC^1gUn{n;Ge-&5-y zj0`%)bitFR17?RV8XjSP_rtj!qJvM>BjOmIM_+CQ_5T(2XRP9J9SRSA)jNn12;~H&MG1%Vaor z;pzyF69>3DqvJpG#%zLAK8-(NS6=ztJ2scW)!v{6 z(P*Cf98`jio93GRDP)bOy1Kd;n3A4M((>?mA--XA0S%*srov0vcD{x3KBdT1)BDIi_*(Jbc!iD z#fE-b@VfT48>!dXb+*ZDu>J9sq#M#}@cn%dWuQ=G#Kg-UY%DB=m6c=WTy9?QMuV?5 z(HMU-`v8h-JDP5jn$Ul*TUPibPS6&4yIhy6o@`#h++8R~ zN1@BXmu7mmu|C|}eg5K8#82FKVjqZ|HRof-&azyqq%S?Iy>pWbnC%oUS^dIj>E(no z9RI=nk2%WAg0fvT#Ab&P7eh*aw2(2G1Ud+$S2#rzKB>FY-;qaAhDrN}embcRR z`Qzh1tT0zY!+9S(k>3>{TKn0rkAB_LCR%l<^X7R3>PaUP<4w)mD{DX9zE}3&YOA>M z>Sdh>BM1YdW&Xr4Y8;D`f)F0~`v*1ky{1;?=Hr#N`pU|YW9)>W#F>)vwCc;P9^4v% zf~PB+``*P64E(N^7T>YW>gs9`wmNDpBcq@4b4;<-V{?V_JtD9Kg*f`+kZof+Rx#9bz z@IgMN+nLa_$-CaIJmHGQJblHHA|4;OUuj?}3O6^}G&Y6!x4F;S(A*D=m%kUG;xlzs z6gd-SPKM$82yo8{dspoHKbISun@ER0L8)TsO%&K9QY{MG4c7n2%=t?GZam&Kq{bWx zoyL1p$MeCg4lr=8g^P#hl-{`f&{+b7@$7MtZ06Qv`TAtJm5$r2RS_~vJ>OH_K_h?U z;lqcbC!LDpsjI822-Jl3aBi&sBLwBPhDJ@+B(#-%vBb@_`G($*tGjyCi z{?554*17kr``7*B&T=jF<74)>_kQYkv-v&b03Ij(nUq9uk+)<+T!6gr%5^h zoJXh5*-cQJ27e0-cZS}WiUn~hNFolr=1c{PN{4w=fveI<2zC?222MEsAeg z9M^~I8&p9fNb7d?;TOo!s3h*|-vb>Kmxdq9P2V>!JEb-VnmP0{Y;HXR-fFt5w<@6E zz(etaXz1wtgD*E|?UU`;6?F4GdL?o88c?Uv*cd%|pB_;LhNspMqrt94t22us5a%^Q}`YJ8Q zJjrJ!C(kA=OSVw(aMbBCBFQ>jK%F)G=$i?S4!J7s;ZY5~z$9~V?ywY!rCuxNX)PU= zy8Ez&lcFO2wL=XIHU#Bz@Bzp1%uPQYVOnRuBqbyB2;Rk=xGY@EQ{Ma4hc({;Cye7?T#)B;9sHFzEQeXknYAI5+0@Dy(vnFJfDu~@g4 zQ&f(D<_kORlVLmbhCeEg;O5JTU>;8XQ|5ajY91aAwfVs8is&my{DWWXxo%9HqylJC zE>{gCw}hjAxtb0v1aP=_mYHYS#8R?&v{1PgA7xOh(0-Qiy5aj=@3cov=;ZIM0keaC zd2Q_}wZ{DzUxGVN)K}MEM9@}$+a`s$L=-0qdSJ-(x7CZCifL=K`yE&aJ8z6JeB^G4Kq&r)|{|WM5?_f0@_8Y{8{$(aY!% z*jKbA*v9t$-xEwhB#94pu!uG11JX;z!D#SJxXMd&LyHsbD1d zd3l@1`MlP?y!AbGJm3OIrCgM~rHXtdC@AQQyM{i%V#k>3#-9Zx0#Bbl1!kt%x?PcA zcSeYn6)!jAi^y+INi1K7^Zuz(vTts!S&x~uuf@JflRF}qn3}CyEXt->oStM@=}ep3 z96U~%DR@Wnpiq6~>NJh@N#%VoT#e7wiay*><-M97+3LD<^XUO`?0Nh~`5RVNyQ_a-Zp`^4KDH&ye5eE4C->u_ii~vgUbZx8YvJO6p zLVcZ%T@w9un#uXnK`k9-W^C7S@;ML<}Pq3rhrZ9eiF804p!8X(-atPwXr~6Q$2>oDN7NZ0u}P zTv9YqDJ+`+ApN@&kq{Y~mPY)`^d`jV!Uc!&xMNO;!*lCFub8R$*{Im{8=2j`@W*4% zwtc|GRE)qI0~~p6Eh#V;cJL0cEJf0*9gepJR3ZHX1JT7gmX%@CH6C$+`&Cf9kj!yu z=z?MKmt-&k1yN&HOiN3dF30}i+7`;Cy1$!fABNg;(L(i^I=p4jOpBTy9bso@qspYx zXlSOz4;n`W=-dkuEvMzC7Z6Bp=+Q}T2d>dV=X7{o9dVK3{a`e}xbrr4TpWRKQ@AOm z_7cpvnVXAibaK=hHZhv>tGZ!W_|4$X#go2)0a8lRrdi}%WdsVoQ+nSYl`*t-YoEmt zfVrB9*+rK#5Nf6%QT*q407Q(9MBEy~#zqeb4@PSdedQws?d!wzn2 zeBMw}+&`$Y^(ofpN-CBv#*;@EmXYAwX2gBmGO~grUtc+9vx`>b56d^s0&bG+YeTV0a8-ZgQ*6q)0;gxIRO+Pz`Uqd0|+2C_Cxig39S4v z{PFkFHs3)#2j&F|P7c0Uk`ZeRT zk>LF8qIOn@X&ztyDjY2vpcI-)PQas}=(l-8N@8ZEZ&TLy{n1evs`B6tz&C+fqFr&7 z{iTuf5zs!okz@4X(TplmS5DDVW92lIaFSD6+Z}=$ZJ``@gFV`UAAl~UcZhyX5Y){; z>l5K>={=+Qfn|N6%7HW|Cr5)qLPVtH?n?M)pa*TFt@ZSp)XCbtcc;KuS91eJj?;YK zq-tUU3so6Oi3j>5!h?fr+cy{rJHo>HL9iOwJ`Wr|IvScsj~};p^th7uUFMEFKyv+N z(}$yyv@}ob-ggiFQx2GXk4!`4akW^~j2kaptrbrIY;jWAXuzCLBBw+p3)uH61 z*bg2=b{pDoz{jCgVEGUU2`<|+
vY<%N8NUF##Qy6W5^1{=n){)UN3_z2yKE_2s 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 literal 0 HcmV?d00001 diff --git "a/function/communication/wifi/p2ptest/doc/image/\345\272\224\347\224\250\351\241\265\351\235\242.png" "b/function/communication/wifi/p2ptest/doc/image/\345\272\224\347\224\250\351\241\265\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..feaf8e62873ea17add1605254d625d29102d5748 GIT binary patch literal 24456 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 snt~_I$2$f_II}@`swsRmK4eQFc=Uq)Jv2LJ#7 literal 0 HcmV?d00001 diff --git "a/function/communication/wifi/p2ptest/doc/image/\346\234\215\345\212\241\347\253\257\346\265\201\347\250\213.png" "b/function/communication/wifi/p2ptest/doc/image/\346\234\215\345\212\241\347\253\257\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..88d5b80c6db302a69be9b320880e6d408a251ca4 GIT binary patch literal 80603 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 VTr.default.createHash(u);u.hash=(D,e)=>(0,u.createHash)(e).update(D).digest("hex");u.hashFile=(D,e)=>{if(i.default.existsSync(D))return(0,u.hash)(i.default.readFileSync(D,"utf-8"),e)}}(v);var g={},m={},R={};Object.defineProperty(R,"__esModule",{value:!0}),R.Unicode=void 0;class y{}R.Unicode=y,y.SPACE_SEPARATOR=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,y.ID_START=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,y.ID_CONTINUE=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(m,"__esModule",{value:!0}),m.JudgeUtil=void 0;const I=R;m.JudgeUtil=class{static isIgnoreChar(u){return"string"==typeof u&&("\t"===u||"\v"===u||"\f"===u||" "===u||" "===u||"\ufeff"===u||"\n"===u||"\r"===u||"\u2028"===u||"\u2029"===u)}static isSpaceSeparator(u){return"string"==typeof u&&I.Unicode.SPACE_SEPARATOR.test(u)}static isIdStartChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||I.Unicode.ID_START.test(u))}static isIdContinueChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||I.Unicode.ID_CONTINUE.test(u))}static isDigitWithoutZero(u){return/[1-9]/.test(u)}static isDigit(u){return"string"==typeof u&&/[0-9]/.test(u)}static isHexDigit(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};var N=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(g,"__esModule",{value:!0}),g.parseJsonText=g.parseJsonFile=void 0;const b=N(e),S=N(D),w=N(u),H=m;var x;!function(u){u[u.Char=0]="Char",u[u.EOF=1]="EOF",u[u.Identifier=2]="Identifier"}(x||(x={}));let M,T,V,G,j,J,W="start",U=[],L=0,$=1,k=0,K=!1,z="default",q="'",Z=1;function X(u,D=!1){T=String(u),W="start",U=[],L=0,$=1,k=0,G=void 0,K=D;do{M=Q(),nu[W]()}while("eof"!==M.type);return G}function Q(){for(z="default",j="",q="'",Z=1;;){J=Y();const u=Du[z]();if(u)return u}}function Y(){if(T[L])return String.fromCodePoint(T.codePointAt(L))}function uu(){const u=Y();return"\n"===u?($++,k=0):u?k+=u.length:k++,u&&(L+=u.length),u}g.parseJsonFile=function(u,D=!1,e="utf-8"){const t=b.default.readFileSync(w.default.resolve(u),{encoding:e});try{return X(t,D)}catch(D){if(D instanceof SyntaxError){const e=D.message.split("at");if(2===e.length)throw new Error(`${e[0].trim()}${S.default.EOL}\t at ${u}:${e[1].trim()}`)}throw new Error(`${u} is not in valid JSON/JSON5 format.`)}},g.parseJsonText=X;const Du={default(){switch(J){case"/":return uu(),void(z="comment");case void 0:return uu(),eu("eof")}if(!H.JudgeUtil.isIgnoreChar(J)&&!H.JudgeUtil.isSpaceSeparator(J))return Du[W]();uu()},start(){z="value"},beforePropertyName(){switch(J){case"$":case"_":return j=uu(),void(z="identifierName");case"\\":return uu(),void(z="identifierNameStartEscape");case"}":return eu("punctuator",uu());case'"':case"'":return q=J,uu(),void(z="string")}if(H.JudgeUtil.isIdStartChar(J))return j+=uu(),void(z="identifierName");throw Eu(x.Char,uu())},afterPropertyName(){if(":"===J)return eu("punctuator",uu());throw Eu(x.Char,uu())},beforePropertyValue(){z="value"},afterPropertyValue(){switch(J){case",":case"}":return eu("punctuator",uu())}throw Eu(x.Char,uu())},beforeArrayValue(){if("]"===J)return eu("punctuator",uu());z="value"},afterArrayValue(){switch(J){case",":case"]":return eu("punctuator",uu())}throw Eu(x.Char,uu())},end(){throw Eu(x.Char,uu())},comment(){switch(J){case"*":return uu(),void(z="multiLineComment");case"/":return uu(),void(z="singleLineComment")}throw Eu(x.Char,uu())},multiLineComment(){switch(J){case"*":return uu(),void(z="multiLineCommentAsterisk");case void 0:throw Eu(x.Char,uu())}uu()},multiLineCommentAsterisk(){switch(J){case"*":return void uu();case"/":return uu(),void(z="default");case void 0:throw Eu(x.Char,uu())}uu(),z="multiLineComment"},singleLineComment(){switch(J){case"\n":case"\r":case"\u2028":case"\u2029":return uu(),void(z="default");case void 0:return uu(),eu("eof")}uu()},value(){switch(J){case"{":case"[":return eu("punctuator",uu());case"n":return uu(),tu("ull"),eu("null",null);case"t":return uu(),tu("rue"),eu("boolean",!0);case"f":return uu(),tu("alse"),eu("boolean",!1);case"-":case"+":return"-"===uu()&&(Z=-1),void(z="numerical");case".":case"0":case"I":case"N":return void(z="numerical");case'"':case"'":return q=J,uu(),j="",void(z="string")}if(void 0===J||!H.JudgeUtil.isDigitWithoutZero(J))throw Eu(x.Char,uu());z="numerical"},numerical(){switch(J){case".":return j=uu(),void(z="decimalPointLeading");case"0":return j=uu(),void(z="zero");case"I":return uu(),tu("nfinity"),eu("numeric",Z*(1/0));case"N":return uu(),tu("aN"),eu("numeric",NaN)}if(void 0!==J&&H.JudgeUtil.isDigitWithoutZero(J))return j=uu(),void(z="decimalInteger");throw Eu(x.Char,uu())},zero(){switch(J){case".":case"e":case"E":return void(z="decimal");case"x":case"X":return j+=uu(),void(z="hexadecimal")}return eu("numeric",0)},decimalInteger(){switch(J){case".":case"e":case"E":return void(z="decimal")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimal(){switch(J){case".":j+=uu(),z="decimalFraction";break;case"e":case"E":j+=uu(),z="decimalExponent"}},decimalPointLeading(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalFraction");throw Eu(x.Char,uu())},decimalFraction(){switch(J){case"e":case"E":return j+=uu(),void(z="decimalExponent")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimalExponent(){switch(J){case"+":case"-":return j+=uu(),void(z="decimalExponentSign")}if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentSign(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentInteger(){if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},hexadecimal(){if(H.JudgeUtil.isHexDigit(J))return j+=uu(),void(z="hexadecimalInteger");throw Eu(x.Char,uu())},hexadecimalInteger(){if(!H.JudgeUtil.isHexDigit(J))return eu("numeric",Z*Number(j));j+=uu()},identifierNameStartEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":break;default:if(!H.JudgeUtil.isIdStartChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},identifierName(){switch(J){case"$":case"_":case"‌":case"‍":return void(j+=uu());case"\\":return uu(),void(z="identifierNameEscape")}if(!H.JudgeUtil.isIdContinueChar(J))return eu("identifier",j);j+=uu()},identifierNameEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!H.JudgeUtil.isIdContinueChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},string(){switch(J){case"\\":return uu(),void(j+=function(){const u=Y(),D=function(){switch(Y()){case"b":return uu(),"\b";case"f":return uu(),"\f";case"n":return uu(),"\n";case"r":return uu(),"\r";case"t":return uu(),"\t";case"v":return uu(),"\v"}return}();if(D)return D;switch(u){case"0":if(uu(),H.JudgeUtil.isDigit(Y()))throw Eu(x.Char,uu());return"\0";case"x":return uu(),function(){let u="",D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());if(u+=uu(),D=Y(),!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());return u+=uu(),String.fromCodePoint(parseInt(u,16))}();case"u":return uu(),ru();case"\n":case"\u2028":case"\u2029":return uu(),"";case"\r":return uu(),"\n"===Y()&&uu(),""}if(void 0===u||H.JudgeUtil.isDigitWithoutZero(u))throw Eu(x.Char,uu());return uu()}());case'"':case"'":if(J===q){const u=eu("string",j);return uu(),u}return void(j+=uu());case"\n":case"\r":case void 0:throw Eu(x.Char,uu());case"\u2028":case"\u2029":!function(u){console.warn(`JSON5: '${Fu(u)}' in strings is not valid ECMAScript; consider escaping.`)}(J)}j+=uu()}};function eu(u,D){return{type:u,value:D,line:$,column:k}}function tu(u){for(const D of u){if(Y()!==D)throw Eu(x.Char,uu());uu()}}function ru(){let u="",D=4;for(;D-- >0;){const D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());u+=uu()}return String.fromCodePoint(parseInt(u,16))}const nu={start(){if("eof"===M.type)throw Eu(x.EOF);iu()},beforePropertyName(){switch(M.type){case"identifier":case"string":return V=M.value,void(W="afterPropertyName");case"punctuator":return void Cu();case"eof":throw Eu(x.EOF)}},afterPropertyName(){if("eof"===M.type)throw Eu(x.EOF);W="beforePropertyValue"},beforePropertyValue(){if("eof"===M.type)throw Eu(x.EOF);iu()},afterPropertyValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforePropertyName");case"}":Cu()}},beforeArrayValue(){if("eof"===M.type)throw Eu(x.EOF);"punctuator"!==M.type||"]"!==M.value?iu():Cu()},afterArrayValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforeArrayValue");case"]":Cu()}},end(){}};function iu(){const u=function(){let u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}return u}();if(K&&"object"==typeof u&&(u._line=$,u._column=k),void 0===G)G=u;else{const D=U[U.length-1];Array.isArray(D)?K&&"object"!=typeof u?D.push({value:u,_line:$,_column:k}):D.push(u):D[V]=K&&"object"!=typeof u?{value:u,_line:$,_column:k}:u}!function(u){if(u&&"object"==typeof u)U.push(u),W=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}}(u)}function Cu(){U.pop();const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}function Fu(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return`\\x${`00${D}`.substring(D.length)}`}return u}function Eu(u,D){let e="";switch(u){case x.Char:e=void 0===D?`JSON5: invalid end of input at ${$}:${k}`:`JSON5: invalid character '${Fu(D)}' at ${$}:${k}`;break;case x.EOF:e=`JSON5: invalid end of input at ${$}:${k}`;break;case x.Identifier:k-=5,e=`JSON5: invalid identifier character at ${$}:${k}`}const t=new Au(e);return t.lineNumber=$,t.columnNumber=k,t}class Au extends SyntaxError{}var ou={},au=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),cu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),su=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&au(D,u,e);return cu(D,u),D},lu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(ou,"__esModule",{value:!0}),ou.isFileExists=ou.offlinePluginConversion=ou.executeCommand=ou.getNpmPath=ou.hasNpmPackInPaths=void 0;const Bu=r,du=lu(e),fu=su(u),_u=i,pu=l;ou.hasNpmPackInPaths=function(u,D){try{return require.resolve(u,{paths:[...D]}),!0}catch(u){return!1}},ou.getNpmPath=function(){const u=process.execPath;return fu.join(fu.dirname(u),_u.NPM_TOOL)},ou.executeCommand=function(u,D,e){0!==(0,Bu.spawnSync)(u,D,e).status&&(0,pu.logErrorAndExit)(`Error: ${u} ${D} execute failed.See above for details.`)},ou.offlinePluginConversion=function(u,D){return D.startsWith("file:")||D.endsWith(".tgz")?fu.resolve(u,_u.HVIGOR,D.replace("file:","")):D},ou.isFileExists=function(u){return du.default.existsSync(u)&&du.default.statSync(u).isFile()};var Ou=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),hu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),Pu=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&Ou(D,u,e);return hu(D,u),D},vu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(P,"__esModule",{value:!0});var gu=P.initProjectWorkSpace=void 0;const mu=Pu(e),Ru=vu(D),yu=Pu(u),Iu=v,Nu=i,bu=g,Su=l,wu=ou;let Hu,xu,Mu;function Tu(u,D,e){return void 0!==e.dependencies&&(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,D.dependencies[u])===yu.normalize(e.dependencies[u])}function Vu(){const u=yu.join(Mu,Nu.WORK_SPACE);if((0,Su.logInfoPrintConsole)("Hvigor cleaning..."),!mu.existsSync(u))return;const D=mu.readdirSync(u);if(!D||0===D.length)return;const e=yu.resolve(Mu,"node_modules","@ohos","hvigor","bin","hvigor.js");mu.existsSync(e)&&(0,wu.executeCommand)(process.argv[0],[e,"--stop-daemon"],{});try{D.forEach((D=>{mu.rmSync(yu.resolve(u,D),{recursive:!0})}))}catch(D){(0,Su.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${u}.`)}}gu=P.initProjectWorkSpace=function(){if(Hu=function(){const u=yu.resolve(Nu.HVIGOR_PROJECT_WRAPPER_HOME,Nu.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);mu.existsSync(u)||(0,Su.logErrorAndExit)(`Error: Hvigor config file ${u} does not exist.`);return(0,bu.parseJsonFile)(u)}(),Mu=function(u){let D;D=function(u){let D=u.hvigorVersion;if(D.startsWith("file:")||D.endsWith(".tgz"))return!1;const e=u.dependencies,t=Object.getOwnPropertyNames(e);for(const u of t){const D=e[u];if(D.startsWith("file:")||D.endsWith(".tgz"))return!1}if(1===t.length&&"@ohos/hvigor-ohos-plugin"===t[0])return D>"2.5.0";return!1}(u)?function(u){let D=`${Nu.HVIGOR_ENGINE_PACKAGE_NAME}@${u.hvigorVersion}`;const e=u.dependencies;if(e){Object.getOwnPropertyNames(e).sort().forEach((u=>{D+=`,${u}@${e[u]}`}))}return(0,Iu.hash)(D)}(u):(0,Iu.hash)(process.cwd());return yu.resolve(Ru.default.homedir(),".hvigor","project_caches",D)}(Hu),xu=function(){const u=yu.resolve(Mu,Nu.WORK_SPACE,Nu.DEFAULT_PACKAGE_JSON);return mu.existsSync(u)?(0,bu.parseJsonFile)(u):{dependencies:{}}}(),!(0,wu.hasNpmPackInPaths)(Nu.HVIGOR_ENGINE_PACKAGE_NAME,[yu.join(Mu,Nu.WORK_SPACE)])||(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion)!==xu.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]||!function(){function u(u){const D=null==u?void 0:u.dependencies;return void 0===D?0:Object.getOwnPropertyNames(D).length}const D=u(Hu),e=u(xu);if(D+1!==e)return!1;for(const u in null==Hu?void 0:Hu.dependencies)if(!(0,wu.hasNpmPackInPaths)(u,[yu.join(Mu,Nu.WORK_SPACE)])||!Tu(u,Hu,xu))return!1;return!0}()){Vu();try{!function(){(0,Su.logInfoPrintConsole)("Hvigor installing...");for(const u in Hu.dependencies)Hu.dependencies[u]&&(Hu.dependencies[u]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.dependencies[u]));const u={dependencies:{...Hu.dependencies}};u.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion);const D=yu.join(Mu,Nu.WORK_SPACE);try{mu.mkdirSync(D,{recursive:!0});const e=yu.resolve(D,Nu.DEFAULT_PACKAGE_JSON);mu.writeFileSync(e,JSON.stringify(u))}catch(u){(0,Su.logErrorAndExit)(u)}(function(){const u=["config","set","store-dir",Nu.HVIGOR_PNPM_STORE_PATH],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)})(),function(){const u=["install"],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)}(),(0,Su.logInfoPrintConsole)("Hvigor install success.")}()}catch(u){Vu()}}return Mu};var Gu={};!function(t){var C=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),F=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),E=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&C(D,u,e);return F(D,u),D},A=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(t,"__esModule",{value:!0}),t.executeInstallPnpm=t.isPnpmInstalled=t.environmentHandler=t.checkNpmConifg=t.PNPM_VERSION=void 0;const o=r,a=E(e),c=A(D),s=E(u),B=i,d=l,f=ou;t.PNPM_VERSION="7.30.0",t.checkNpmConifg=function(){const u=s.resolve(B.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),D=s.resolve(c.default.homedir(),".npmrc");if((0,f.isFileExists)(u)||(0,f.isFileExists)(D))return;const e=(0,f.getNpmPath)(),t=(0,o.spawnSync)(e,["config","get","prefix"],{cwd:B.HVIGOR_PROJECT_ROOT_DIR});if(0!==t.status||!t.stdout)return void(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const r=s.resolve(`${t.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,f.isFileExists)(r)||(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},t.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},t.isPnpmInstalled=function(){return!!a.existsSync(B.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,f.hasNpmPackInPaths)("pnpm",[B.HVIGOR_WRAPPER_TOOLS_HOME])},t.executeInstallPnpm=function(){(0,d.logInfoPrintConsole)(`Installing pnpm@${t.PNPM_VERSION}...`);const u=(0,f.getNpmPath)();!function(){const u=s.resolve(B.HVIGOR_WRAPPER_TOOLS_HOME,B.DEFAULT_PACKAGE_JSON);try{a.existsSync(B.HVIGOR_WRAPPER_TOOLS_HOME)||a.mkdirSync(B.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const D={dependencies:{}};D.dependencies[B.PNPM]=t.PNPM_VERSION,a.writeFileSync(u,JSON.stringify(D))}catch(D){(0,d.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${u} failed.`)}}(),(0,f.executeCommand)(u,["install","pnpm"],{cwd:B.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,d.logInfoPrintConsole)("Pnpm install success.")}}(Gu),function(){Gu.checkNpmConifg(),Gu.environmentHandler(),Gu.isPnpmInstalled()||Gu.executeInstallPnpm();const D=gu();_(u.join(D,i.WORK_SPACE))}(); \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/hvigorfile.ts b/function/communication/wifi/p2ptest/hvigorfile.ts new file mode 100644 index 000000000..7523fdc92 --- /dev/null +++ b/function/communication/wifi/p2ptest/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/function/communication/wifi/p2ptest/hvigorw b/function/communication/wifi/p2ptest/hvigorw new file mode 100644 index 000000000..a822c433c --- /dev/null +++ b/function/communication/wifi/p2ptest/hvigorw @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME="`pwd -P`" +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +#NODE_OPTS="--max-old-space-size=4096" + +fail() { + echo "$*" + exit 1 +} + +set_executable_node() { + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + + EXECUTABLE_NODE="${NODE_HOME}/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ]; then + set_executable_node +else + EXECUTABLE_NODE="node" + command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +if [ -z "${NODE_OPTS}" ]; then + NODE_OPTS="--" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/function/communication/wifi/p2ptest/hvigorw.bat b/function/communication/wifi/p2ptest/hvigorw.bat new file mode 100644 index 000000000..6599c1faf --- /dev/null +++ b/function/communication/wifi/p2ptest/hvigorw.bat @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +@rem +@rem ---------------------------------------------------------------------------- +@rem Hvigor startup script for Windows, version 1.0.0 +@rem +@rem Required ENV vars: +@rem ------------------ +@rem NODE_HOME - location of a Node home dir +@rem or +@rem Add %NODE_HOME%/bin to the PATH environment variable +@rem ---------------------------------------------------------------------------- +@rem +@echo off + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe +@rem set NODE_OPTS="--max-old-space-size=4096" + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +if not defined NODE_OPTS set NODE_OPTS="--" + +@rem Find node.exe +if defined NODE_HOME ( + set NODE_HOME=%NODE_HOME:"=% + set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% +) + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else if exist "%NODE_EXE_PATH%" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else ( + echo. + echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. + echo. + echo Please set the NODE_HOME variable in your environment to match the + echo location of your NodeJs installation. +) + +if "%ERRORLEVEL%" == "0" ( + if "%OS%" == "Windows_NT" endlocal +) else ( + exit /b %ERRORLEVEL% +) \ No newline at end of file diff --git a/function/communication/wifi/p2ptest/oh-package.json5 b/function/communication/wifi/p2ptest/oh-package.json5 new file mode 100644 index 000000000..d231caf29 --- /dev/null +++ b/function/communication/wifi/p2ptest/oh-package.json5 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +{ + "name": "wifip2p", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.13", + "@ohos/hamock": "1.0.0" + } +} -- Gitee From 0b4d85371897977149205f5a967e13e1b479ef05 Mon Sep 17 00:00:00 2001 From: wangshi Date: Thu, 23 Jan 2025 17:01:02 +0800 Subject: [PATCH 4/4] add p2p app Signed-off-by: wangshi --- function/communication/wifi/p2ptest/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/function/communication/wifi/p2ptest/README.md b/function/communication/wifi/p2ptest/README.md index 9313d15d8..3b2158554 100644 --- a/function/communication/wifi/p2ptest/README.md +++ b/function/communication/wifi/p2ptest/README.md @@ -21,7 +21,7 @@ ets image-20241107104059577.png -客户端界面可配置传输次数和数据长度,每次传输包含 101 个数据包,每个包中的元素范围从 0 至 100。例如,第 1 个数据包中所有元素均为 0,其长度依据应用设定。依此类推,客户端在每次回调中统计元素值为 1 至 100 的数据包数量和总长度,再通过发送首个元素值为 199 的包来标志传输结束。 +客户端界面可配置传输次数和数据长度,每次传输包含 101 个数据包,每个包中的元素范围从 0 至 100。例如,第 1 个数据包中所有元素均为 0,其长度依据应用设定。依此类推,客户端在每次回调中统计元素值为 1 至 100 的数据包数量和总长度,再通过发送元素值为 199 的包来标志传输结束。 服务端接收数据流程如下图所示。 @@ -57,4 +57,4 @@ image-20241107163922918.png 可能原因:服务端开发板 WLAN 未打开 -解决办法:进入设置-WLAN,打开 WLAN 状态,切掉 wifiP2P 应用后台并重新进入,再点击“测试服务端”按钮 \ No newline at end of file +解决办法:进入设置-WLAN,打开 WLAN 状态,切掉 wifiP2P 应用后台并重新进入,再点击“测试服务端”按钮 -- Gitee