From b076ee6d9a3198300e8f8094ba2d70ed0fa10306 Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:23:31 +0300 Subject: [PATCH 01/23] minSdkVersion is updated to 19 for compatibility reasons --- example/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index c2adee8..8b93256 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -34,7 +34,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.tuanpm.esp_provisioning_example" - minSdkVersion 16 + minSdkVersion 19 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName From 2f5a914015e8fde40fd31585ddaba3fd99679794 Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:24:34 +0300 Subject: [PATCH 02/23] If BT is already on at Android devices, it hangs at start() function, it is fixed --- example/lib/ble_service.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/example/lib/ble_service.dart b/example/lib/ble_service.dart index febd56f..460d189 100644 --- a/example/lib/ble_service.dart +++ b/example/lib/ble_service.dart @@ -50,12 +50,13 @@ class BleService { }); }); + var state = await _waitForBluetoothPoweredOn(); if (Platform.isAndroid) { - log.v('enableRadio'); - await _bleManager.enableRadio(); + if (state.index != 3) { // check if bluetooth is already open + log.v('enableRadio'); + await _bleManager.enableRadio(); + } } - - var state = await _waitForBluetoothPoweredOn(); _isPowerOn = true; return state; } From dd530a31dfb448d4183d315a46c25290cd6d082d Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:25:41 +0300 Subject: [PATCH 03/23] peripheral parameter is passed to WiFiScreen --- example/lib/ble_screen/ble_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/ble_screen/ble_screen.dart b/example/lib/ble_screen/ble_screen.dart index 296624d..8e84808 100644 --- a/example/lib/ble_screen/ble_screen.dart +++ b/example/lib/ble_screen/ble_screen.dart @@ -34,7 +34,7 @@ class _BleScreenState extends State { return Container( padding: EdgeInsets.only(top: 5.0), height: MediaQuery.of(context).size.height - 50, - child: WiFiScreen(), + child: WiFiScreen(peripheral: item), ); }); bottomSheetController.whenComplete(() { From 56506749ed096f588054f8248b538665d3f0b287 Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:26:07 +0300 Subject: [PATCH 04/23] peripheral select code is added before provisioning --- example/lib/wifi_screen/wifi_bloc.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/example/lib/wifi_screen/wifi_bloc.dart b/example/lib/wifi_screen/wifi_bloc.dart index 7197842..51168ef 100644 --- a/example/lib/wifi_screen/wifi_bloc.dart +++ b/example/lib/wifi_screen/wifi_bloc.dart @@ -18,6 +18,7 @@ class WifiBloc extends Bloc { WifiEvent event, ) async* { if (event is WifiEventLoad) { + bleService.select(event.selectedDevice['peripheral']); yield* _mapLoadToState(); } else if (event is WifiEventStartProvisioning) { yield* _mapProvisioningToState(event); From dda3cec81e9e94943ab01e44cd138c027371b2f4 Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:26:25 +0300 Subject: [PATCH 05/23] WifiEventLoad is edited for peripheral parameter pass --- example/lib/wifi_screen/wifi_event.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/example/lib/wifi_screen/wifi_event.dart b/example/lib/wifi_screen/wifi_event.dart index d9ae0ea..ae4e9cc 100644 --- a/example/lib/wifi_screen/wifi_event.dart +++ b/example/lib/wifi_screen/wifi_event.dart @@ -7,7 +7,14 @@ abstract class WifiEvent extends Equatable { List get props => []; } -class WifiEventLoad extends WifiEvent {} +class WifiEventLoad extends WifiEvent { + final Map selectedDevice; + + const WifiEventLoad(this.selectedDevice); + + @override + List get props => [selectedDevice]; +} class WifiEventConnecting extends WifiEvent {} From 91e3562917fcddcc7698288eacbbf619527e3417 Mon Sep 17 00:00:00 2001 From: omert08 Date: Mon, 15 Mar 2021 14:26:44 +0300 Subject: [PATCH 06/23] peripheral is passed to WiFiBloc --- example/lib/wifi_screen/wifi_screen.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/lib/wifi_screen/wifi_screen.dart b/example/lib/wifi_screen/wifi_screen.dart index 42ef7f2..54074d1 100644 --- a/example/lib/wifi_screen/wifi_screen.dart +++ b/example/lib/wifi_screen/wifi_screen.dart @@ -7,8 +7,8 @@ import 'wifi.dart'; import 'wifi_dialog.dart'; class WiFiScreen extends StatefulWidget { - WiFiScreen({Key key}) : super(key: key); - + Map peripheral; + WiFiScreen({Key key, this.peripheral}) : super(key: key); @override _WiFiScreenState createState() => _WiFiScreenState(); } @@ -114,7 +114,7 @@ class _WiFiScreenState extends State { ), ), body: BlocProvider( - create: (BuildContext context) => WifiBloc()..add(WifiEventLoad()), + create: (BuildContext context) => WifiBloc()..add(WifiEventLoad(widget.peripheral)), child: BlocBuilder( builder: (BuildContext context, WifiState state) { if (state is WifiStateConnecting) { From 6e1ccd051c8774009df63f641ae1431ceb8592de Mon Sep 17 00:00:00 2001 From: omert08 Date: Sat, 20 Mar 2021 22:56:47 +0300 Subject: [PATCH 07/23] TransPortHTTP class constructor is done --- lib/src/transport_http.dart | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/src/transport_http.dart diff --git a/lib/src/transport_http.dart b/lib/src/transport_http.dart new file mode 100644 index 0000000..35fa6bc --- /dev/null +++ b/lib/src/transport_http.dart @@ -0,0 +1,58 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'package:flutter/material.dart'; + +import 'transport.dart'; +import 'dart:io'; +import 'package:string_validator/string_validator.dart'; + +class TransPortHTTP implements ProvTransport{ + HttpClient client = new HttpClient(); + String hostname; + int port; + Map headers; + SecurityContext ssl_context; + + TransPortHTTP(String hostname, int port, SecurityContext ssl_context) { + if (!isIP(hostname)){ + throw FormatException('hostname should be an IP address.'); + } + else{ + this.hostname = hostname; + } + this.port = port; + + if (ssl_context == null){ + this.ssl_context = ssl_context; + } + this.client.connectionTimeout = Duration(seconds: 45); + + try { + print('Connecting to' + this.hostname); + client.open('GET', this.hostname, this.port,''); + print('Connection is successful'); + this.headers = {'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain'}; + } + catch(e){ + print('Connection error ' + e.toString()); + } + + @override + Future connect() { + // TODO: implement connect + throw UnimplementedError(); + } + + @override + Future disconnect() { + // TODO: implement disconnect + throw UnimplementedError(); + } + + @override + Future sendReceive(String epName, Uint8List data) { + // TODO: implement sendReceive + throw UnimplementedError(); + } +} + From 8e30a648f28f36d22ba41edaf5f61aa2f3317d88 Mon Sep 17 00:00:00 2001 From: omert08 Date: Sat, 20 Mar 2021 22:57:58 +0300 Subject: [PATCH 08/23] overrides are added --- lib/src/transport_http.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/transport_http.dart b/lib/src/transport_http.dart index 35fa6bc..b81f9fe 100644 --- a/lib/src/transport_http.dart +++ b/lib/src/transport_http.dart @@ -56,3 +56,4 @@ class TransPortHTTP implements ProvTransport{ } } + From 1af03c1dd241605fcd9ad3f3bf178cf7398367b1 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 10:08:32 +0300 Subject: [PATCH 09/23] Transporthttp constuctor is edited --- example/lib/softap_service.dart | 18 +++++++++ lib/src/transport_http.dart | 66 ++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 example/lib/softap_service.dart diff --git a/example/lib/softap_service.dart b/example/lib/softap_service.dart new file mode 100644 index 0000000..3697281 --- /dev/null +++ b/example/lib/softap_service.dart @@ -0,0 +1,18 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter_ble_lib/flutter_ble_lib.dart'; +import 'package:logger/logger.dart'; +import 'package:esp_provisioning/esp_provisioning.dart'; +import 'package:permission_handler/permission_handler.dart'; +class WiFiService { + Future startProvisioning( + {Peripheral peripheral, String pop = 'abcd1234'}) async { + EspProv prov = EspProv( + transport: TransportHTTP("192.168.4.1", 80)); + var success = await prov.establishSession(); + if (!success) { + throw Exception('Error establishSession'); + } + return prov; + } +} \ No newline at end of file diff --git a/lib/src/transport_http.dart b/lib/src/transport_http.dart index b81f9fe..e7995d3 100644 --- a/lib/src/transport_http.dart +++ b/lib/src/transport_http.dart @@ -1,4 +1,6 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:html'; import 'dart:typed_data'; import 'package:flutter/material.dart'; @@ -6,41 +8,37 @@ import 'transport.dart'; import 'dart:io'; import 'package:string_validator/string_validator.dart'; -class TransPortHTTP implements ProvTransport{ +class TransportHTTP implements ProvTransport{ HttpClient client = new HttpClient(); String hostname; - int port; - Map headers; - SecurityContext ssl_context; - - TransPortHTTP(String hostname, int port, SecurityContext ssl_context) { - if (!isIP(hostname)){ + final int port; + //Map headers; + TransportHTTP(String hostname, this.port) { + if (!isIP(hostname)) { throw FormatException('hostname should be an IP address.'); } - else{ + else { this.hostname = hostname; } - this.port = port; - - if (ssl_context == null){ - this.ssl_context = ssl_context; - } this.client.connectionTimeout = Duration(seconds: 45); + } + @override + Future connect() async { + HttpClientRequest request; try { print('Connecting to' + this.hostname); - client.open('GET', this.hostname, this.port,''); - print('Connection is successful'); - this.headers = {'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain'}; + request = await this.client.post(this.hostname, this.port,'/'); + request.headers.set(HttpHeaders.contentTypeHeader, 'application/x-www-form-urlencoded'); + request.headers.set(HttpHeaders.acceptHeader, 'text/plain'); + await request.close(); + print('Connection successful'); + return true; } catch(e){ print('Connection error ' + e.toString()); - } + } - @override - Future connect() { - // TODO: implement connect - throw UnimplementedError(); } @override @@ -50,10 +48,28 @@ class TransPortHTTP implements ProvTransport{ } @override - Future sendReceive(String epName, Uint8List data) { - // TODO: implement sendReceive - throw UnimplementedError(); + Future sendReceive(String epName, Uint8List data) async { + HttpClientRequest request; + try { + print('Connecting to' + this.hostname); + request = await this.client.post(this.hostname, this.port, epName); + request.headers.set( + HttpHeaders.contentTypeHeader, 'application/x-www-form-urlencoded'); + request.headers.set(HttpHeaders.acceptHeader, 'text/plain'); + request.write(data); + print('Connection successful'); + } + catch (e) { + print('Connection error ' + e.toString()); + } + final response = await request.close(); + response.transform(utf8.decoder).listen((contents) { + print(contents); + }); + + return Uint8List(5); + } } -} + From 9f2db57bfe240a8a293b97ed49e82659abf10426 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 10:09:33 +0300 Subject: [PATCH 10/23] transport http is exported --- lib/esp_provisioning.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/esp_provisioning.dart b/lib/esp_provisioning.dart index 1fa3897..a395bde 100644 --- a/lib/esp_provisioning.dart +++ b/lib/esp_provisioning.dart @@ -2,4 +2,5 @@ export 'src/esp_prov.dart'; export 'src/security.dart'; export 'src/security1.dart'; export 'src/transport.dart'; -export 'src/transport_ble.dart'; \ No newline at end of file +export 'src/transport_ble.dart'; +export 'src/transport_http.dart'; \ No newline at end of file From 7ef305e379cd656a67c056a700226c4a098922cd Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 10:31:44 +0300 Subject: [PATCH 11/23] softap events are added --- example/lib/wifi_screen/wifi_event.dart | 54 ++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/example/lib/wifi_screen/wifi_event.dart b/example/lib/wifi_screen/wifi_event.dart index ae4e9cc..9e91c0e 100644 --- a/example/lib/wifi_screen/wifi_event.dart +++ b/example/lib/wifi_screen/wifi_event.dart @@ -7,36 +7,72 @@ abstract class WifiEvent extends Equatable { List get props => []; } -class WifiEventLoad extends WifiEvent { +// events for BLE provisioning +class WifiEventLoadBLE extends WifiEvent { final Map selectedDevice; - const WifiEventLoad(this.selectedDevice); + const WifiEventLoadBLE(this.selectedDevice); @override List get props => [selectedDevice]; } -class WifiEventConnecting extends WifiEvent {} +class WifiEventConnectingBLE extends WifiEvent {} -class WifiEventScanning extends WifiEvent {} +class WifiEventScanningBLE extends WifiEvent {} -class WifiEventScanned extends WifiEvent {} +class WifiEventScannedBLE extends WifiEvent {} -class WifiEventLoaded extends WifiEvent { +class WifiEventLoadedBLE extends WifiEvent { final String wifiName; - WifiEventLoaded({this.wifiName}); + WifiEventLoadedBLE({this.wifiName}); @override List get props => [wifiName]; } -class WifiEventStartProvisioning extends WifiEvent { +class WifiEventStartProvisioningBLE extends WifiEvent { final String ssid; final String password; - WifiEventStartProvisioning({this.ssid, this.password}); + WifiEventStartProvisioningBLE({this.ssid, this.password}); @override List get props => [ssid, password]; } + +// events for softap provisioning +class WifiEventLoadSoftAP extends WifiEvent { + final Map selectedDevice; + + const WifiEventLoadSoftAP(this.selectedDevice); + + @override + List get props => [selectedDevice]; +} + +class WifiEventConnectingSoftAP extends WifiEvent {} + +class WifiEventScanningSoftAP extends WifiEvent {} + +class WifiEventScannedSoftAP extends WifiEvent {} + +class WifiEventLoadedSoftAP extends WifiEvent { + final String wifiName; + + WifiEventLoadedSoftAP({this.wifiName}); + + @override + List get props => [wifiName]; +} + +class WifiEventStartProvisioningSoftAP extends WifiEvent { + final String ssid; + final String password; + + WifiEventStartProvisioningSoftAP({this.ssid, this.password}); + + @override + List get props => [ssid, password]; +} \ No newline at end of file From 7bc00c21a7c68a6ce1bbf1ce47eb6fd7352c405e Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 11:36:28 +0300 Subject: [PATCH 12/23] wifibloc is isolated for ble prov. --- example/lib/wifi_screen/wifi_bloc.dart | 8 ++++---- example/lib/wifi_screen/wifi_screen.dart | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/example/lib/wifi_screen/wifi_bloc.dart b/example/lib/wifi_screen/wifi_bloc.dart index 51168ef..d46cf90 100644 --- a/example/lib/wifi_screen/wifi_bloc.dart +++ b/example/lib/wifi_screen/wifi_bloc.dart @@ -5,7 +5,7 @@ import 'package:logger/logger.dart'; import '../ble_service.dart'; import './wifi.dart'; -class WifiBloc extends Bloc { +class WifiBlocBLE extends Bloc { var bleService = BleService.getInstance(); EspProv prov; Logger log = Logger(printer: PrettyPrinter()); @@ -17,10 +17,10 @@ class WifiBloc extends Bloc { Stream mapEventToState( WifiEvent event, ) async* { - if (event is WifiEventLoad) { + if (event is WifiEventLoadBLE) { bleService.select(event.selectedDevice['peripheral']); yield* _mapLoadToState(); - } else if (event is WifiEventStartProvisioning) { + } else if (event is WifiEventStartProvisioningBLE) { yield* _mapProvisioningToState(event); } } @@ -46,7 +46,7 @@ class WifiBloc extends Bloc { } Stream _mapProvisioningToState( - WifiEventStartProvisioning event) async* { + WifiEventStartProvisioningBLE event) async* { yield WifiStateProvisioning(); await prov?.sendWifiConfig(ssid: event.ssid, password: event.password); await prov?.applyWifiConfig(); diff --git a/example/lib/wifi_screen/wifi_screen.dart b/example/lib/wifi_screen/wifi_screen.dart index 54074d1..5379938 100644 --- a/example/lib/wifi_screen/wifi_screen.dart +++ b/example/lib/wifi_screen/wifi_screen.dart @@ -22,8 +22,8 @@ class _WiFiScreenState extends State { wifiName: wifi['ssid'], onSubmit: (ssid, password) { print('ssid =$ssid, password = $password'); - BlocProvider.of(_context).add( - WifiEventStartProvisioning(ssid: ssid, password: password)); + BlocProvider.of(_context).add( + WifiEventStartProvisioningBLE(ssid: ssid, password: password)); }, ); }); @@ -114,8 +114,8 @@ class _WiFiScreenState extends State { ), ), body: BlocProvider( - create: (BuildContext context) => WifiBloc()..add(WifiEventLoad(widget.peripheral)), - child: BlocBuilder( + create: (BuildContext context) => WifiBlocBLE()..add(WifiEventLoadBLE(widget.peripheral)), + child: BlocBuilder( builder: (BuildContext context, WifiState state) { if (state is WifiStateConnecting) { return _buildStepper(0, state); From 5daf74c3a04301865bc474fc6fd73a9d441621e6 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 12:13:03 +0300 Subject: [PATCH 13/23] WiFiBlocSoftAP is added --- example/lib/softap_service.dart | 14 +++++----- example/lib/wifi_screen/wifi_bloc.dart | 37 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/example/lib/softap_service.dart b/example/lib/softap_service.dart index 3697281..f1168b8 100644 --- a/example/lib/softap_service.dart +++ b/example/lib/softap_service.dart @@ -1,14 +1,16 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter_ble_lib/flutter_ble_lib.dart'; -import 'package:logger/logger.dart'; import 'package:esp_provisioning/esp_provisioning.dart'; -import 'package:permission_handler/permission_handler.dart'; -class WiFiService { - Future startProvisioning( - {Peripheral peripheral, String pop = 'abcd1234'}) async { + +class SoftAPService { + final String hostname; + final int port; + SoftAPService(this.hostname, this.port); + + Future startProvisioning() async { EspProv prov = EspProv( - transport: TransportHTTP("192.168.4.1", 80)); + transport: TransportHTTP(this.hostname, this.port)); var success = await prov.establishSession(); if (!success) { throw Exception('Error establishSession'); diff --git a/example/lib/wifi_screen/wifi_bloc.dart b/example/lib/wifi_screen/wifi_bloc.dart index d46cf90..dddf33b 100644 --- a/example/lib/wifi_screen/wifi_bloc.dart +++ b/example/lib/wifi_screen/wifi_bloc.dart @@ -3,6 +3,7 @@ import 'package:bloc/bloc.dart'; import 'package:esp_provisioning/esp_provisioning.dart'; import 'package:logger/logger.dart'; import '../ble_service.dart'; +import '../softap_service.dart'; import './wifi.dart'; class WifiBlocBLE extends Bloc { @@ -60,3 +61,39 @@ class WifiBlocBLE extends Bloc { return super.close(); } } + +class WiFiBlocSoftAP extends Bloc { + var softApService = SoftAPService("192.168.4.1", 80); + EspProv prov; + Logger log = Logger(printer: PrettyPrinter()); + + @override + // TODO: implement initialState + WifiState get initialState => WifiStateLoading(); + + @override + Stream mapEventToState(WifiEvent event) async* { + if (event is WifiEventLoadSoftAP) { + yield* _mapLoadToState(); + } + } + + Stream _mapLoadToState() async*{ + yield WifiStateConnecting(); + try { + prov = await softApService.startProvisioning(); + } catch (e) { + log.e('Error conencting to device $e'); + yield WifiStateError('Error conencting to device'); + } + yield WifiStateScanning(); + try { + var listWifi = await prov.startScanWiFi(); + yield WifiStateLoaded(wifiList: listWifi ?? []); + log.v('Wifi $listWifi'); + } catch (e) { + log.e('Error scan WiFi network $e'); + yield WifiStateError('Error scan WiFi network'); + } + } +} From 217f6f37b53a51fe7ba6a561db2e2ca27122a9fb Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 12:14:29 +0300 Subject: [PATCH 14/23] load event is edited --- example/lib/wifi_screen/wifi_event.dart | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/example/lib/wifi_screen/wifi_event.dart b/example/lib/wifi_screen/wifi_event.dart index 9e91c0e..5d6af4d 100644 --- a/example/lib/wifi_screen/wifi_event.dart +++ b/example/lib/wifi_screen/wifi_event.dart @@ -43,14 +43,7 @@ class WifiEventStartProvisioningBLE extends WifiEvent { } // events for softap provisioning -class WifiEventLoadSoftAP extends WifiEvent { - final Map selectedDevice; - - const WifiEventLoadSoftAP(this.selectedDevice); - - @override - List get props => [selectedDevice]; -} +class WifiEventLoadSoftAP extends WifiEvent {} class WifiEventConnectingSoftAP extends WifiEvent {} From 1b27056f1ec98d6d119a7792f009e4a1d2f46f6b Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 12:16:08 +0300 Subject: [PATCH 15/23] dart:html is removed --- example/lib/wifi_screen/wifi_screen.dart | 6 +++--- lib/src/transport_http.dart | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/lib/wifi_screen/wifi_screen.dart b/example/lib/wifi_screen/wifi_screen.dart index 5379938..031bbc6 100644 --- a/example/lib/wifi_screen/wifi_screen.dart +++ b/example/lib/wifi_screen/wifi_screen.dart @@ -22,8 +22,8 @@ class _WiFiScreenState extends State { wifiName: wifi['ssid'], onSubmit: (ssid, password) { print('ssid =$ssid, password = $password'); - BlocProvider.of(_context).add( - WifiEventStartProvisioningBLE(ssid: ssid, password: password)); + BlocProvider.of(_context).add( + WifiEventStartProvisioningSoftAP(ssid: ssid, password: password)); }, ); }); @@ -114,7 +114,7 @@ class _WiFiScreenState extends State { ), ), body: BlocProvider( - create: (BuildContext context) => WifiBlocBLE()..add(WifiEventLoadBLE(widget.peripheral)), + create: (BuildContext context) => WifiBlocBLE()..add(WifiEventLoadSoftAP()), child: BlocBuilder( builder: (BuildContext context, WifiState state) { if (state is WifiStateConnecting) { diff --git a/lib/src/transport_http.dart b/lib/src/transport_http.dart index e7995d3..ed8e277 100644 --- a/lib/src/transport_http.dart +++ b/lib/src/transport_http.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:html'; import 'dart:typed_data'; import 'package:flutter/material.dart'; @@ -37,6 +36,7 @@ class TransportHTTP implements ProvTransport{ } catch(e){ print('Connection error ' + e.toString()); + return false; } } From 70d45cc4f81f6a831832fe0e9056dceaf64625ef Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 15:50:34 +0300 Subject: [PATCH 16/23] softapbloc is created --- example/lib/softap_screen/softap_bloc.dart | 22 ++++++++++++++++++++ example/lib/softap_screen/softap_event.dart | 0 example/lib/softap_screen/softap_screen.dart | 0 example/lib/softap_screen/softap_state.dart | 0 4 files changed, 22 insertions(+) create mode 100644 example/lib/softap_screen/softap_bloc.dart create mode 100644 example/lib/softap_screen/softap_event.dart create mode 100644 example/lib/softap_screen/softap_screen.dart create mode 100644 example/lib/softap_screen/softap_state.dart diff --git a/example/lib/softap_screen/softap_bloc.dart b/example/lib/softap_screen/softap_bloc.dart new file mode 100644 index 0000000..f087912 --- /dev/null +++ b/example/lib/softap_screen/softap_bloc.dart @@ -0,0 +1,22 @@ + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:esp_provisioning_example/softap_screen/softap_event.dart'; +import 'package:esp_provisioning_example/softap_screen/softap_state.dart'; +import 'package:esp_provisioning_example/softap_service.dart'; + + + +class SoftApBloc extends Bloc { + var softApService = SoftAPService("192.168.4.1", 80); + + @override + // TODO: implement initialState + get initialState => SoftApStateLoaded(); + + @override + Stream mapEventToState(SoftApEvent) async* { + // TODO: implement mapEventToState + throw UnimplementedError(); + } + +} \ No newline at end of file diff --git a/example/lib/softap_screen/softap_event.dart b/example/lib/softap_screen/softap_event.dart new file mode 100644 index 0000000..e69de29 diff --git a/example/lib/softap_screen/softap_screen.dart b/example/lib/softap_screen/softap_screen.dart new file mode 100644 index 0000000..e69de29 diff --git a/example/lib/softap_screen/softap_state.dart b/example/lib/softap_screen/softap_state.dart new file mode 100644 index 0000000..e69de29 From b2c56894c46cafbaf07847b4cb335096a0f5bc00 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 15:51:08 +0300 Subject: [PATCH 17/23] softap initial events are added --- example/lib/softap_screen/softap_event.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/example/lib/softap_screen/softap_event.dart b/example/lib/softap_screen/softap_event.dart index e69de29..2b8b697 100644 --- a/example/lib/softap_screen/softap_event.dart +++ b/example/lib/softap_screen/softap_event.dart @@ -0,0 +1,8 @@ +import 'package:equatable/equatable.dart'; + +abstract class SoftApEvent extends Equatable { + const SoftApEvent(); + + @override + List get props => []; +} \ No newline at end of file From 951abf90593334c8a9d31dc1da86cf70c3f4df28 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 15:51:30 +0300 Subject: [PATCH 18/23] soft ap screen code is created --- example/lib/softap_screen/softap_screen.dart | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/example/lib/softap_screen/softap_screen.dart b/example/lib/softap_screen/softap_screen.dart index e69de29..3b8c6e0 100644 --- a/example/lib/softap_screen/softap_screen.dart +++ b/example/lib/softap_screen/softap_screen.dart @@ -0,0 +1,38 @@ +import 'package:esp_provisioning_example/softap_screen/softap_bloc.dart'; +import 'package:esp_provisioning_example/softap_screen/softap_event.dart'; +import 'package:esp_provisioning_example/softap_screen/softap_state.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; + +class SoftApScreen extends StatefulWidget { + @override + _SoftApScreenState createState() => _SoftApScreenState(); +} + +class _SoftApScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.redAccent, + title: const Text('Scanning BLE devices'), + ), + body: BlocProvider( + create: (BuildContext context) => SoftApBloc(), + child: BlocBuilder( + builder: (BuildContext context, SoftApState state) { + if (state is SoftApStateLoaded) { + return Center( + child: Text('Please connect WiFi to Subol_Gas_Sensor_*** device in "Wi-Fi Settings"'), + ); + } + return Center( + child: SpinKitRipple(color: Theme.of(context).textSelectionColor), + ); + }, + ), + ), + ); + } +} From 62587ed1d7b6c53c7528a10f100925e3c765a380 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 15:55:52 +0300 Subject: [PATCH 19/23] Softap state initial states are created --- example/lib/softap_screen/softap_state.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/example/lib/softap_screen/softap_state.dart b/example/lib/softap_screen/softap_state.dart index e69de29..d89e041 100644 --- a/example/lib/softap_screen/softap_state.dart +++ b/example/lib/softap_screen/softap_state.dart @@ -0,0 +1,10 @@ +import 'package:equatable/equatable.dart'; + +abstract class SoftApState extends Equatable { + const SoftApState(); + + @override + List get props => []; +} + +class SoftApStateLoaded extends SoftApState {} From 7452170678a4382a2e41caa92d211424fc6f76f0 Mon Sep 17 00:00:00 2001 From: omert08 Date: Fri, 26 Mar 2021 16:52:22 +0300 Subject: [PATCH 20/23] softap screen is created --- example/lib/softap_screen/softap_screen.dart | 36 +++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/example/lib/softap_screen/softap_screen.dart b/example/lib/softap_screen/softap_screen.dart index 3b8c6e0..2db3970 100644 --- a/example/lib/softap_screen/softap_screen.dart +++ b/example/lib/softap_screen/softap_screen.dart @@ -24,9 +24,43 @@ class _SoftApScreenState extends State { builder: (BuildContext context, SoftApState state) { if (state is SoftApStateLoaded) { return Center( - child: Text('Please connect WiFi to Subol_Gas_Sensor_*** device in "Wi-Fi Settings"'), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + padding: EdgeInsets.all(4.0), + width: MediaQuery.of(context).size.width * 0.85, + child:Text('Please connect WiFi to Subol_Gas_Sensor_ in "Wi-Fi Settings". Once you complete it please click Ready button.', + style: TextStyle(fontSize: 18),), + ), + + SizedBox(height: MediaQuery.of(context).size.width * 0.1,), + MaterialButton( + color: Colors.redAccent, + elevation: 5, + padding: EdgeInsets.all(15.0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(5))), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => SoftApScreen())); + }, + child: Text( + 'Ready', + style: Theme.of(context) + .textTheme + .headline6 + .copyWith(color: Colors.white), + ), + ), + ], + ) + ); } + return Center( child: SpinKitRipple(color: Theme.of(context).textSelectionColor), ); From 795e648cab0b764c4e3734d2a0c5f65c36356f90 Mon Sep 17 00:00:00 2001 From: omert08 Date: Sat, 27 Mar 2021 14:31:30 +0300 Subject: [PATCH 21/23] Android manifest is edited for http requests and internet usage --- example/android/app/src/main/AndroidManifest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 8c369ef..caa9e56 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -5,9 +5,11 @@ In most cases you can leave this as-is, but you if you want to provide additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> + + From 3ee3f3250ee7249e4fff681623a81f5712299baa Mon Sep 17 00:00:00 2001 From: omert08 Date: Sat, 27 Mar 2021 20:47:19 +0300 Subject: [PATCH 22/23] no important updates --- example/ios/Podfile | 87 ---------------------------------------- example/ios/Podfile.lock | 41 ------------------- example/pubspec.lock | 75 +++++++++++++++++++++++++--------- example/pubspec.yaml | 1 + 4 files changed, 56 insertions(+), 148 deletions(-) delete mode 100644 example/ios/Podfile delete mode 100644 example/ios/Podfile.lock diff --git a/example/ios/Podfile b/example/ios/Podfile deleted file mode 100644 index 6697f0a..0000000 --- a/example/ios/Podfile +++ /dev/null @@ -1,87 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; - end - generated_key_values = {} - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) do |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - generated_key_values[podname] = podpath - else - puts "Invalid plugin specification: #{line}" - end - end - generated_key_values -end - -target 'Runner' do - use_frameworks! - use_modular_headers! - - # Flutter Pod - - copied_flutter_dir = File.join(__dir__, 'Flutter') - copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') - copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') - unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) - # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. - # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. - # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. - - generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') - unless File.exist?(generated_xcode_build_settings_path) - raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) - cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; - - unless File.exist?(copied_framework_path) - FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) - end - unless File.exist?(copied_podspec_path) - FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) - end - end - - # Keep pod path relative so it can be checked into Podfile.lock. - pod 'Flutter', :path => 'Flutter' - - # Plugin Pods - - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.each do |name, path| - symlink = File.join('.symlinks', 'plugins', name) - File.symlink(path, symlink) - pod name, :path => File.join(symlink, 'ios') - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - end - end -end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock deleted file mode 100644 index 789bb2f..0000000 --- a/example/ios/Podfile.lock +++ /dev/null @@ -1,41 +0,0 @@ -PODS: - - esp_provisioning (0.0.1): - - Flutter - - Flutter (1.0.0) - - flutter_ble_lib (2.2.3): - - Flutter - - MultiplatformBleAdapter (= 0.1.5) - - MultiplatformBleAdapter (0.1.5) - - "permission_handler (5.0.0+hotfix.3)": - - Flutter - -DEPENDENCIES: - - esp_provisioning (from `.symlinks/plugins/esp_provisioning/ios`) - - Flutter (from `Flutter`) - - flutter_ble_lib (from `.symlinks/plugins/flutter_ble_lib/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - -SPEC REPOS: - trunk: - - MultiplatformBleAdapter - -EXTERNAL SOURCES: - esp_provisioning: - :path: ".symlinks/plugins/esp_provisioning/ios" - Flutter: - :path: Flutter - flutter_ble_lib: - :path: ".symlinks/plugins/flutter_ble_lib/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" - -SPEC CHECKSUMS: - esp_provisioning: f23d52f966f1de0f66007d805220abb52f61a2f1 - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - flutter_ble_lib: 20e79f0b1d78d921d9ed68ab4451e190029bc3d9 - MultiplatformBleAdapter: 3c4391d428382738a47662ae1f665a29ce78ff39 - permission_handler: 4a985b5448897c27fdeadde84f7452520c0e6c58 - -PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a - -COCOAPODS: 1.9.0.beta.2 diff --git a/example/pubspec.lock b/example/pubspec.lock index 0186d91..f841f5a 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.5.0" bloc: dependency: transitive description: @@ -21,28 +21,35 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0" convert: dependency: transitive description: @@ -84,14 +91,14 @@ packages: path: ".." relative: true source: path - version: "1.0.0+4" + version: "1.0.0+5" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" fixnum: dependency: transitive description: @@ -130,6 +137,20 @@ packages: description: flutter source: sdk version: "0.0.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" io: dependency: transitive description: @@ -157,14 +178,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0" nested: dependency: transitive description: @@ -178,7 +199,14 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.0" permission_handler: dependency: "direct main" description: @@ -239,56 +267,63 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" + string_validator: + dependency: "direct main" + description: + name: string_validator + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.12.8" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 26af80a..d7b75e4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: flutter_spinkit: ^4.1.2+1 cupertino_icons: ^0.1.3 + string_validator: ^0.3.0 dev_dependencies: flutter_test: From 081eb817e94922272a932120e9168d81042021b1 Mon Sep 17 00:00:00 2001 From: omert08 Date: Sat, 27 Mar 2021 20:49:11 +0300 Subject: [PATCH 23/23] It works with softap provisioning on Android untill EstablishSession event --- example/lib/ble_screen/ble_screen.dart | 2 +- example/lib/main.dart | 3 +- example/lib/softap_screen/softap_bloc.dart | 15 +- example/lib/softap_screen/softap_event.dart | 4 +- example/lib/softap_screen/softap_screen.dart | 41 ++++- example/lib/softap_service.dart | 2 +- example/lib/wifi_screen/wifi_bloc.dart | 6 +- example/lib/wifi_screen/wifi_screen.dart | 181 ++++++++++++++++++- 8 files changed, 224 insertions(+), 30 deletions(-) diff --git a/example/lib/ble_screen/ble_screen.dart b/example/lib/ble_screen/ble_screen.dart index 8e84808..a9d0975 100644 --- a/example/lib/ble_screen/ble_screen.dart +++ b/example/lib/ble_screen/ble_screen.dart @@ -34,7 +34,7 @@ class _BleScreenState extends State { return Container( padding: EdgeInsets.only(top: 5.0), height: MediaQuery.of(context).size.height - 50, - child: WiFiScreen(peripheral: item), + child: WiFiScreenBLE(peripheral: item), ); }); bottomSheetController.whenComplete(() { diff --git a/example/lib/main.dart b/example/lib/main.dart index 4e3a3dc..3bf0e05 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:esp_provisioning_example/softap_screen/softap_screen.dart'; import 'package:flutter/material.dart'; import 'ble_screen/ble_screen.dart'; @@ -26,7 +27,7 @@ class HomeScreen extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => BleScreen())); + builder: (BuildContext context) => SoftApScreen())); }, child: Text( 'Start Provisioning', diff --git a/example/lib/softap_screen/softap_bloc.dart b/example/lib/softap_screen/softap_bloc.dart index f087912..2949617 100644 --- a/example/lib/softap_screen/softap_bloc.dart +++ b/example/lib/softap_screen/softap_bloc.dart @@ -7,16 +7,19 @@ import 'package:esp_provisioning_example/softap_service.dart'; class SoftApBloc extends Bloc { - var softApService = SoftAPService("192.168.4.1", 80); @override // TODO: implement initialState get initialState => SoftApStateLoaded(); @override - Stream mapEventToState(SoftApEvent) async* { - // TODO: implement mapEventToState - throw UnimplementedError(); - } + Stream mapEventToState(event) async* { + if (event is SoftApEventStart){ + yield* _mapStartToState(); + } + } + Stream _mapStartToState() async* { + + } +} -} \ No newline at end of file diff --git a/example/lib/softap_screen/softap_event.dart b/example/lib/softap_screen/softap_event.dart index 2b8b697..12efecd 100644 --- a/example/lib/softap_screen/softap_event.dart +++ b/example/lib/softap_screen/softap_event.dart @@ -5,4 +5,6 @@ abstract class SoftApEvent extends Equatable { @override List get props => []; -} \ No newline at end of file +} + +class SoftApEventStart extends SoftApEvent {} \ No newline at end of file diff --git a/example/lib/softap_screen/softap_screen.dart b/example/lib/softap_screen/softap_screen.dart index 2db3970..ce6f455 100644 --- a/example/lib/softap_screen/softap_screen.dart +++ b/example/lib/softap_screen/softap_screen.dart @@ -1,6 +1,7 @@ import 'package:esp_provisioning_example/softap_screen/softap_bloc.dart'; import 'package:esp_provisioning_example/softap_screen/softap_event.dart'; import 'package:esp_provisioning_example/softap_screen/softap_state.dart'; +import 'package:esp_provisioning_example/wifi_screen/wifi.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; @@ -11,6 +12,34 @@ class SoftApScreen extends StatefulWidget { } class _SoftApScreenState extends State { + + void _showBottomSheet(BuildContext _context) { + // BlocProvider.of(_context).add(SoftApEventStart()); + + var bottomSheetController = showModalBottomSheet( + context: context, + backgroundColor: Colors.white, + isScrollControlled: true, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: const Radius.circular(20.0), + topRight: const Radius.circular(20.0), + ), + ), + builder: (BuildContext context) { + return Container( + padding: EdgeInsets.only(top: 5.0), + height: MediaQuery.of(context).size.height - 50, + child: WiFiScreenSoftAP(), + ); + }); + bottomSheetController.whenComplete(() { + // after prov. + BlocProvider.of(_context).add(SoftApEventStart()); + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -30,7 +59,7 @@ class _SoftApScreenState extends State { Container( padding: EdgeInsets.all(4.0), width: MediaQuery.of(context).size.width * 0.85, - child:Text('Please connect WiFi to Subol_Gas_Sensor_ in "Wi-Fi Settings". Once you complete it please click Ready button.', + child:Text('Please connect WiFi to Subol_Gas_Sensor_ in "Wi-Fi Settings". Once you complete it please tap on "Ready" button.', style: TextStyle(fontSize: 18),), ), @@ -41,12 +70,6 @@ class _SoftApScreenState extends State { padding: EdgeInsets.all(15.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(5))), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => SoftApScreen())); - }, child: Text( 'Ready', style: Theme.of(context) @@ -54,6 +77,10 @@ class _SoftApScreenState extends State { .headline6 .copyWith(color: Colors.white), ), + + onPressed: () { + _showBottomSheet(this.context); + }, ), ], ) diff --git a/example/lib/softap_service.dart b/example/lib/softap_service.dart index f1168b8..e9ea7ac 100644 --- a/example/lib/softap_service.dart +++ b/example/lib/softap_service.dart @@ -10,7 +10,7 @@ class SoftAPService { Future startProvisioning() async { EspProv prov = EspProv( - transport: TransportHTTP(this.hostname, this.port)); + transport: TransportHTTP(this.hostname, this.port), security: Security1(pop: 'abcd1234')); var success = await prov.establishSession(); if (!success) { throw Exception('Error establishSession'); diff --git a/example/lib/wifi_screen/wifi_bloc.dart b/example/lib/wifi_screen/wifi_bloc.dart index dddf33b..f91db6c 100644 --- a/example/lib/wifi_screen/wifi_bloc.dart +++ b/example/lib/wifi_screen/wifi_bloc.dart @@ -63,7 +63,7 @@ class WifiBlocBLE extends Bloc { } class WiFiBlocSoftAP extends Bloc { - var softApService = SoftAPService("192.168.4.1", 80); + var softApService = SoftAPService("192.168.4.1:80", 80); EspProv prov; Logger log = Logger(printer: PrettyPrinter()); @@ -83,8 +83,8 @@ class WiFiBlocSoftAP extends Bloc { try { prov = await softApService.startProvisioning(); } catch (e) { - log.e('Error conencting to device $e'); - yield WifiStateError('Error conencting to device'); + log.e('Error connecting to device $e'); + yield WifiStateError('Error connecting to device'); } yield WifiStateScanning(); try { diff --git a/example/lib/wifi_screen/wifi_screen.dart b/example/lib/wifi_screen/wifi_screen.dart index 031bbc6..be4ef39 100644 --- a/example/lib/wifi_screen/wifi_screen.dart +++ b/example/lib/wifi_screen/wifi_screen.dart @@ -1,3 +1,4 @@ +import 'package:esp_provisioning_example/ble_screen/ble_bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; @@ -6,14 +7,15 @@ import '../scan_list.dart'; import 'wifi.dart'; import 'wifi_dialog.dart'; -class WiFiScreen extends StatefulWidget { +// ignore: must_be_immutable +class WiFiScreenBLE extends StatefulWidget { Map peripheral; - WiFiScreen({Key key, this.peripheral}) : super(key: key); + WiFiScreenBLE({Key key, this.peripheral}) : super(key: key); @override - _WiFiScreenState createState() => _WiFiScreenState(); + _WiFiScreenBLEState createState() => _WiFiScreenBLEState(); } -class _WiFiScreenState extends State { +class _WiFiScreenBLEState extends State { void _showDialog(Map wifi, BuildContext _context) { showDialog( context: _context, @@ -22,8 +24,8 @@ class _WiFiScreenState extends State { wifiName: wifi['ssid'], onSubmit: (ssid, password) { print('ssid =$ssid, password = $password'); - BlocProvider.of(_context).add( - WifiEventStartProvisioningSoftAP(ssid: ssid, password: password)); + BlocProvider.of(_context).add( + WifiEventStartProvisioningBLE(ssid: ssid, password: password)); }, ); }); @@ -33,7 +35,7 @@ class _WiFiScreenState extends State { List _statusWidget = [ Column( children: [ - FlatButton.icon( + ElevatedButton.icon( onPressed: () {}, icon: SpinKitThreeBounce( color: Colors.black, @@ -44,7 +46,7 @@ class _WiFiScreenState extends State { ), Column( children: [ - FlatButton.icon( + ElevatedButton.icon( onPressed: () {}, icon: Icon( Icons.check, @@ -56,7 +58,7 @@ class _WiFiScreenState extends State { color: Colors.green, ), )), - FlatButton.icon( + ElevatedButton.icon( onPressed: () {}, icon: SpinKitThreeBounce( color: Colors.black, @@ -114,7 +116,7 @@ class _WiFiScreenState extends State { ), ), body: BlocProvider( - create: (BuildContext context) => WifiBlocBLE()..add(WifiEventLoadSoftAP()), + create: (BuildContext context) => WifiBlocBLE()..add(WifiEventLoadBLE(widget.peripheral)), child: BlocBuilder( builder: (BuildContext context, WifiState state) { if (state is WifiStateConnecting) { @@ -164,3 +166,162 @@ class _WiFiScreenState extends State { ); } } + + +class WiFiScreenSoftAP extends StatefulWidget { + WiFiScreenSoftAP({Key key}) : super(key: key); + @override + _WiFiScreenSoftAPState createState() => _WiFiScreenSoftAPState(); +} + +class _WiFiScreenSoftAPState extends State { + void _showDialog(Map wifi, BuildContext _context) { + showDialog( + context: _context, + builder: (BuildContext context) { + return WifiDialog( + wifiName: wifi['ssid'], + onSubmit: (ssid, password) { + print('ssid =$ssid, password = $password'); + BlocProvider.of(_context).add( + WifiEventStartProvisioningSoftAP(ssid: ssid, password: password)); + }, + ); + }); + } + + Widget _buildStepper(int step, WifiState state) { + List _statusWidget = [ + Column( + children: [ + ElevatedButton.icon( + onPressed: () {}, + icon: SpinKitThreeBounce( + color: Colors.black, + size: 20, + ), + label: Text('Connecting..')) + ], + ), + Column( + children: [ + ElevatedButton.icon( + onPressed: () {}, + icon: Icon( + Icons.check, + color: Colors.green, + ), + label: Text( + 'Connected', + style: TextStyle( + color: Colors.green, + ), + )), + ElevatedButton.icon( + onPressed: () {}, + icon: SpinKitThreeBounce( + color: Colors.black, + size: 20, + ), + label: Text('Scanning...')) + ], + ) + ]; + + var wifiList; + if (state is WifiStateLoaded) { + wifiList = Expanded( + child: ScanList(state.wifiList, Icons.wifi, disableLoading: true, + onTap: (Map item, BuildContext _context) { + _showDialog(item, _context); + })); + } + var body = Expanded(child: Container()); + var statusWidget; + if (step < 2) { + statusWidget = Expanded(child: _statusWidget[step]); + body = Expanded( + child: + SpinKitDoubleBounce(color: Theme.of(context).textSelectionColor)); + } else { + body = wifiList; + } + return Column( + children: [ + Center( + child: Text( + 'Select Wifi network', + style: Theme.of(context).textTheme.headline5, + )), + body, + statusWidget ?? Container(), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + elevation: 0, + iconTheme: IconThemeData( + color: Colors.black, //change your color here + ), + backgroundColor: Colors.transparent, + title: Text( + 'Provisioning...', + style: Theme.of(context).textTheme.bodyText1, + ), + ), + body: BlocProvider( + create: (BuildContext context) => WiFiBlocSoftAP()..add(WifiEventLoadSoftAP()), + child: BlocBuilder( + builder: (BuildContext context, WifiState state) { + if (state is WifiStateConnecting) { + return _buildStepper(0, state); + } + if (state is WifiStateScanning) { + return _buildStepper(1, state); + } + if (state is WifiStateLoaded) { + return _buildStepper(2, state); + } + if (state is WifiStateProvisioning) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SpinKitThreeBounce( + color: Theme.of(context).textSelectionColor, + size: 20, + ), + Text('Provisioning', + style: Theme.of(context).textTheme.bodyText1), + ], + ), + ); + } + if (state is WifiStateProvisioned) { + return Container( + child: Center( + child: MaterialButton(child: Text('Done'), color: Colors.redAccent, onPressed: () { + Navigator.of(context).pop(); + },), + ), + ); + } + return Container( + child: Center( + child: SpinKitThreeBounce( + color: Theme.of(context).textSelectionColor, + size: 20, + ), + ), + ); + }, + ), + ), + ); + } +}