This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3220MODA: AP Provisioning Not Working

Part Number: CC3220MODA

I'm trying to provision a CC3220 using the AP method (SmartConfig works, most of the time, already) from my custom Android app. It's connecting to the device's provisioning AP, and sends the appropriate (I think) requests, and then reconnects to the original access point and starts scanning, but never finds the CC3220 device. Additionally, using a WiFi network scanner, it appears that the CC3220 never turns off its provisioning AP, which I assume it would do when connecting to the AP I'm provisioning it for.

My first function sends a POST request of "__SL_P_P.A=ApSsid&__SL_P_P.B=2&__SL_P_P.C=SuperSecretPassword&__SL_P_P.D=15" to "mysimplelink..net/.../profile_add" and gets a 204 response code.

The second function then sends an empty POST request to "mysimplelink.net/.../confirm_req" and again gets a 204 response code.

Then my app disconnects from the CC3220 AP and reconnects to the original AP and starts scanning for the CC3220, never finding it. Any suggestions?




Here's my relevant Kotlin code from the Android app (you guys should add Kotlin to the syntax highlighter):

   @ExperimentalUnsignedTypes
    suspend fun addProfile(securityType: SecurityType, ssid: String, password: String, priority: UInt = 15u, deviceName: String = ""): Boolean {
        /* Get the device version if necessary */
        if (deviceVersion == SimpleLinkDeviceVersion.UNKNOWN) {
            /* Try twice */
            for (i in 0..1) {
                deviceVersion = getSLVersion()
                if (deviceVersion != SimpleLinkDeviceVersion.UNKNOWN) break
            }
            if (deviceVersion == SimpleLinkDeviceVersion.UNKNOWN) return false
        }

        /* Set the device name if provided */
        if (deviceName.isNotEmpty()) setDeviceName(deviceName)

        /* Strip the quotes from the ssid */
        val cleanedSsid = ssid.substring(1,ssid.length - 1)

        /* Build the URL */
        val urlString = when (deviceVersion) {
            SimpleLinkDeviceVersion.R1 -> "http$baseUrl/profiles_add.html"
            SimpleLinkDeviceVersion.R2 -> if (didRedirect) "https$baseUrl/api/1/wlan/profile_add" else "http$baseUrl/api/1/wlan/profile_add"
            else -> ""
        }

        Log.d(TAG_LOG, "addProfile url: $urlString")

        return withContext(Dispatchers.IO)
        {
            var urlConnection: HttpURLConnection? = null

            try {
                /* Open the URL */
                val url = URL(urlString)
                urlConnection = url.openConnection() as HttpURLConnection

                /* Configure for POST */
                urlConnection.doOutput = true
                urlConnection.connectTimeout = 3000
                urlConnection.readTimeout = 5000
                urlConnection.requestMethod = "POST"

                /* Build and write the POST */
                val request = "${URLEncoder.encode("__SL_P_P.A", "UTF-8")}=${URLEncoder.encode(cleanedSsid, "ISO-8859-1")}&" +
                        "${URLEncoder.encode("__SL_P_P.B", "UTF-8")}=${URLEncoder.encode(securityType.value().toString(), "UTF-8")}&" +
                        "${URLEncoder.encode("__SL_P_P.C", "UTF-8")}=${URLEncoder.encode(password, "UTF-8")}&" +
                        "${URLEncoder.encode("__SL_P_P.D", "UTF-8")}=${URLEncoder.encode(if (priority > 15u) 15u.toString() else priority.toString(), "UTF-8")}"
                Log.d(TAG_LOG, "addProfile POST request: $request")
                urlConnection.outputStream.use {
                    outStream -> outStream.bufferedWriter().use {
                        writer -> writer.write(request)
                        writer.flush()
                    }
                }
                Log.d(TAG_LOG, "Profile added to device.")

                true
            } catch (e: Exception) {
                Log.e(TAG_LOG, "addProfile exception: ${e.message}")
                false
            } finally {
                urlConnection?.disconnect()
            }
        }
    }



    suspend fun moveStateMachineAfterProfileAddition(ssid: String = ""): Boolean {
        /* Build the URL */
        val urlString = when (deviceVersion) {
            SimpleLinkDeviceVersion.R1 -> "http$baseUrl/add_profile.html"
            SimpleLinkDeviceVersion.R2 -> "${if (didRedirect) "https" else "http"}$baseUrl/api/1/wlan/confirm_req"
            else -> return false
        }

        Log.d(TAG_LOG, "moveStateMachineAfterProfileAddition url: $urlString")

        return withContext(Dispatchers.IO) {
            var urlConnection: HttpURLConnection? = null

            try {
                /* Open the URL */
                val url = URL(urlString)
                urlConnection = url.openConnection() as HttpURLConnection

                /* Configure for POST */
                urlConnection.doOutput = true
                urlConnection.connectTimeout = 3000
                urlConnection.readTimeout = 5000
                urlConnection.requestMethod = "POST"

                /* Build and write the POST */
                val request = when (deviceVersion) {
                    SimpleLinkDeviceVersion.R1 -> "${URLEncoder.encode("__SL_P_UAN", "UTF-8")}=${URLEncoder.encode(ssid, "UTF-8")}"
                    else -> ""
                }
                Log.d(TAG_LOG, "moveStateMachineAfterProfileAddition POST request: $request")
                urlConnection.outputStream.use { outStream ->
                    outStream.bufferedWriter().use { writer ->
                        writer.write(request)
                        writer.flush()
                    }
                }
                Log.d(TAG_LOG, "moveStateMachineAfterProfileAddition request sent.")
                true
            } catch (e: MalformedURLException) {
                Log.e(TAG_LOG, "moveStateMachineAfterProfileAddition: malformed URL: ${e.message}")
                false
            } catch (e: IOException) {
                Log.e(TAG_LOG, "moveStateMachineAfterProfileAddition: IO Exception: ${e.message}")
                false
            } catch (e: Exception) {
                Log.e(TAG_LOG, "moveStateMachineAfterProfileAddition: Exception: ${e.message}")
                false
            } finally {
                /* Close everything */
                urlConnection?.disconnect()
            }
        }
    }