Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / android / CHIPTool / app / src / main / java / com / google / chip / chiptool / provisioning / EnterNetworkFragment.kt
1 /*
2  *   Copyright (c) 2020 Project CHIP Authors
3  *   All rights reserved.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  *
17  */
18 package com.google.chip.chiptool.provisioning
19
20 import android.os.Bundle
21 import android.util.Log
22 import android.view.LayoutInflater
23 import android.view.View
24 import android.view.ViewGroup
25 import android.widget.Toast
26 import androidx.fragment.app.Fragment
27 import com.google.chip.chiptool.ChipClient
28 import com.google.chip.chiptool.R
29 import kotlinx.android.synthetic.main.enter_thread_network_fragment.channelEd
30 import kotlinx.android.synthetic.main.enter_thread_network_fragment.masterKeyEd
31 import kotlinx.android.synthetic.main.enter_thread_network_fragment.panIdEd
32 import kotlinx.android.synthetic.main.enter_thread_network_fragment.xpanIdEd
33 import kotlinx.android.synthetic.main.enter_wifi_network_fragment.*
34 import kotlinx.android.synthetic.main.enter_wifi_network_fragment.view.*
35
36 /**
37  * Fragment to collect Wi-Fi network information from user and send it to device being provisioned.
38  */
39 class EnterNetworkFragment : Fragment() {
40
41   private val networkType: ProvisionNetworkType
42     get() = requireNotNull(
43         ProvisionNetworkType.fromName(arguments?.getString(ARG_PROVISION_NETWORK_TYPE))
44     )
45
46   override fun onCreateView(
47       inflater: LayoutInflater,
48       container: ViewGroup?,
49       savedInstanceState: Bundle?
50   ): View? {
51     val layoutRes = when (networkType) {
52       ProvisionNetworkType.WIFI -> R.layout.enter_wifi_network_fragment
53       ProvisionNetworkType.THREAD -> R.layout.enter_thread_network_fragment
54     }
55
56     return inflater.inflate(layoutRes, container, false).apply {
57       saveNetworkBtn.setOnClickListener { onSaveNetworkClicked() }
58     }
59   }
60
61   private fun onSaveNetworkClicked() {
62     if (networkType == ProvisionNetworkType.WIFI) {
63       saveWifiNetwork()
64     } else {
65       saveThreadNetwork()
66     }
67   }
68
69   private fun saveWifiNetwork() {
70     val ssid = ssidEd.text
71     val pwd = pwdEd.text
72
73     if (ssid.isNullOrBlank() || pwd.isNullOrBlank()) {
74       Toast.makeText(requireContext(), "Ssid and password required.", Toast.LENGTH_SHORT).show()
75       return
76     }
77
78     ChipClient.getDeviceController().apply {
79       sendWiFiCredentials(ssid.toString(), pwd.toString())
80     }
81   }
82
83   private fun saveThreadNetwork() {
84     val channelStr = channelEd.text
85     val panIdStr = panIdEd.text
86
87     if (channelStr.isNullOrBlank()) {
88       Toast.makeText(requireContext(), "Channel is empty", Toast.LENGTH_SHORT).show()
89       return
90     }
91
92     if (panIdStr.isNullOrBlank()) {
93       Toast.makeText(requireContext(), "PAN ID is empty", Toast.LENGTH_SHORT).show()
94       return
95     }
96
97     if (xpanIdEd.text.isNullOrBlank()) {
98       Toast.makeText(requireContext(), "XPAN ID is empty", Toast.LENGTH_SHORT).show()
99       return
100     }
101
102     val xpanIdStr = xpanIdEd.text.toString().filterNot { c -> c == ':' }
103     if (xpanIdStr.length != NUM_XPANID_BYTES * 2) {
104       Toast.makeText(requireContext(), "Extended PAN ID is invalid", Toast.LENGTH_SHORT).show()
105       return
106     }
107
108     if (masterKeyEd.text.isNullOrBlank()) {
109       Toast.makeText(requireContext(), "Master Key is empty", Toast.LENGTH_SHORT).show()
110       return
111     }
112
113     val masterKeyStr = masterKeyEd.text.toString().filterNot { c -> c == ':' }
114     if (masterKeyStr.length != NUM_MASTER_KEY_BYTES * 2) {
115       Toast.makeText(requireContext(), "Master key is invalid", Toast.LENGTH_SHORT).show()
116       return
117     }
118
119     ChipClient.getDeviceController().sendThreadCredentials(
120         channelStr.toString().toInt(),
121         panIdStr.toString().toInt(16),
122         xpanIdStr.hexToByteArray(),
123         masterKeyStr.hexToByteArray())
124   }
125
126   private fun String.hexToByteArray(): ByteArray {
127     return chunked(2).map{ byteStr -> byteStr.toUByte(16).toByte()}.toByteArray()
128   }
129
130   companion object {
131     private const val TAG = "EnterNetworkFragment"
132     private const val ARG_PROVISION_NETWORK_TYPE = "provision_network_type"
133     private const val NUM_XPANID_BYTES = 8
134     private const val NUM_MASTER_KEY_BYTES = 16
135
136     fun newInstance(provisionNetworkType: ProvisionNetworkType): EnterNetworkFragment {
137       return EnterNetworkFragment().apply {
138         arguments = Bundle(1).apply {
139           putString(ARG_PROVISION_NETWORK_TYPE, provisionNetworkType.name)
140         }
141       }
142     }
143   }
144
145 }