Forums - Can't connect Wi-Fi - callback never gets called

5 posts / 0 new
Last post
Can't connect Wi-Fi - callback never gets called
david_charlap
Join Date: 3 Apr 19
Posts: 17
Posted: Thu, 2019-05-16 11:48

I'm learning how to use the QAPI calls for networking and I'm trying to get my QCA4020 board to connect to my LAN's Wi-Fi.

I started with the Hello World demo (which works) and added code (to the main thread, outside of the loop) to connect to Wi-Fi.  Once that connects, the plan is to turn on the DHCP client, turn on the DNS client and ping some local device as a part of the Hello World loop.  But the Wi-Fi doesn't connect.

I can connect to my WLAN using the QCLI_demo app and I modeled my code after its WLAN commands.  I think I'm executing the same sequence of commands, but I've clearly missed something because that code works and mine doesn't.  No error messages are generated, so none of the QAPI calls are returning error codes, but the callback function isn't called.

Here's a relevant excerpt from the code (error handling code snipped for brevity).  Can anyone help me determine what I'm doing wrong?

On the surface, it would seem that the Wi-Fi driver's thread (which is supposed to call the callback function) is not running, but I haven't read anything describing what I need to do to start it.

#define CONNECT_EVENT_MASK (0x04)
static qurt_signal_t wifi_event;

static void wifi_callback_function(uint8_t   device_id,
                                   uint32_t  cb_id,     // Callback ID
                                   void     *context,
                                   void     *payload,   // Callback data
                                   uint32_t  payload_len)
{
    Printf("WLAN callback function called\r\n");
    
    switch(cb_id) {
      case QAPI_WLAN_CONNECT_CB_E:
        {
            qapi_WLAN_Connect_Cb_Info_t *info = (qapi_WLAN_Connect_Cb_Info_t *)payload;

            Printf("WLAN connection callback\r\n");
            Printf("   Value: %s\r\n",
                   info->value ? "TRUE (connected)" : "FALSE (disconnected)");
            Printf("   MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
                   info->mac_Addr[0], info->mac_Addr[1], info->mac_Addr[2],
                   info->mac_Addr[3], info->mac_Addr[4], info->mac_Addr[5]);
            Printf("   BSS Connection status: %ld\r\n",
                   info->bss_Connection_Status);

            qurt_signal_set(&wifi_event, CONNECT_EVENT_MASK);
        }
        return;
        
      default:
        Printf("Unsupported callback: dev %d, %ld (context %p, payload %p, len %ld\r\n",
               device_id, cb_id, context, payload, payload_len);
    }
}

void connect_to_wifi(void)
{
    qapi_Status_t status;
    
    status = qapi_WLAN_Enable(QAPI_WLAN_ENABLE_E);
    if (status) {
        Printf("Failed to enable WLAN.  Status: %ld\r\n", status);
        return;
    }

    status = qapi_WLAN_Add_Device(0);
    if (status) {
        Printf("Failed to add WLAN device 0.  Status: %ld\r\n", status);
        return;
    }

    qapi_WLAN_Dev_Mode_e opMode = QAPI_WLAN_DEV_MODE_STATION_E;
    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_OPERATION_MODE,
        &opMode, sizeof(opMode), FALSE);
    if (status) {
        Printf("Failed to set WLAN mode for device 0 to station.  Status: %ld\r\n", status);
        return;
    }
    
    qurt_signal_create(&wifi_event);
    status = qapi_WLAN_Set_Callback(0, wifi_callback_function, NULL);
    if (status) {
        Printf("Failed to register WLAN callback function.  Status: %ld\r\n", status);
        return;
    }

    // WLAN connection parameters - WPA2 + AES
    //
    const char            *ssid       = "MyNetworkSSID";
    const char            *passphrase = "MyNetworkPassphrase";
    qapi_WLAN_Auth_Mode_e  wpa_ver    = QAPI_WLAN_AUTH_WPA2_PSK_E;
    qapi_WLAN_Crypt_Type_e cipher     = QAPI_WLAN_CRYPT_AES_CRYPT_E;

    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_SSID,
        ssid, strlen(ssid), QAPI_WLAN_WAIT_E);
    if (status) {
        Printf("Failed to set SSID to %s (length %d).  Status: %ld\r\n",
               ssid, strlen(ssid), status);
        return;
    }

    uint8_t bssid[6] = {0};       // Don't care about BSSID
    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_BSSID,
        bssid, sizeof(bssid), FALSE);
    if (status) {
        Printf("Failed to set BSSID to %x:%x:%x:%x:%x:%x (length %d).  Status: %ld\r\n",
               bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
               sizeof(bssid), status);
        return;
    }
    
    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_SECURITY,
        __QAPI_WLAN_PARAM_GROUP_SECURITY_ENCRYPTION_TYPE,
        &cipher, sizeof(cipher), FALSE);
    if (status) {
        Printf("Failed to set cipher to %d (length %d).  Status: %ld\r\n",
               cipher, sizeof(cipher), status);
        return;
    }

    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_SECURITY,
        __QAPI_WLAN_PARAM_GROUP_SECURITY_AUTH_MODE,
        &wpa_ver, sizeof(wpa_ver), FALSE);
    if (status) {
        Printf("Failed to set auth mode to %d (length %d).  Status: %ld\r\n",
               wpa_ver, sizeof(wpa_ver), status);
        return;
    }

    status = qapi_WLAN_Set_Param(0,
        __QAPI_WLAN_PARAM_GROUP_WIRELESS_SECURITY,
        __QAPI_WLAN_PARAM_GROUP_SECURITY_PASSPHRASE,
        passphrase, strlen(passphrase), FALSE);
    if (status) {
        Printf("Failed to set passphrase to %s (length %d).  Status: %ld\r\n",
               passphrase, strlen(passphrase), status,);
        return;
    }

    status = qapi_WLAN_Commit(0);
    if (status) {
        Printf("Failed to connect to WLAN.  SSID = %s (len %d)\r\n", ssid, strlen(ssid));
        Printf(".. encryption:%d (len %d), auth:%d (len %d)\r\n",
               cipher, sizeof(cipher), wpa_ver, sizeof(wpa_ver));
        Printf(".. passphrase = %s (len %d).  Status = %ld\r\n",
               passphrase, strlen(passphrase), status);
        return;
    }

    Printf("Successfully started WLAN connect to \"%s\"\r\n", ssid);

    qurt_signal_wait(&wifi_event, CONNECT_EVENT_MASK,
                     QURT_SIGNAL_ATTR_WAIT_ANY | QURT_SIGNAL_ATTR_CLEAR_MASK);

    // !!!! We never get here because the callback never happens

    Printf("... Connection has completed!\r\n");
    
    // The Wi-Fi interface is connected.  Now get the IP network established. ...
    
    ...
}
  • Up0
  • Down0
david_charlap
Join Date: 3 Apr 19
Posts: 17
Posted: Thu, 2019-05-16 12:58

Additionally, it appears that the Wi-Fi hardware is working, because I can successfully scan for access points.  This function (called after the Set_Callback function completes) works just fine and shows me the available networks.

(Error-handling code stripped for brevity, but otherwise identical to what I successfully tested)

static void scan_for_aps(void)
{
    qapi_WLAN_Start_Scan(0, NULL, QAPI_WLAN_BUFFER_SCAN_RESULTS_BLOCKING_E);

    int16_t count = __QAPI_MAX_SCAN_RESULT_ENTRY;
    qapi_WLAN_BSS_Scan_Info_t *info;

    info = calloc(count, sizeof(*info));

    qapi_WLAN_Get_Scan_Results(0, info, &count);

    Printf("Scan results: Found %d SSIDs\r\n", count);

    int i;
    for (i=0; i<count; ++i) {
        char ssid[__QAPI_WLAN_MAX_SSID_LEN + 1];
        qapi_WLAN_BSS_Scan_Info_t *bss = info+i;

        memcpy(ssid, bss->ssid, bss->ssid_Length);
        ssid[bss->ssid_Length] = 0;
        Printf("    %d: %s (%02x:%02x:%02x:%02x:%02x:%02x) (channel %d, RSSI %d)\r\n",
               i+1, ssid,
               bss->bssid[0], bss->bssid[1], bss->bssid[2],
               bss->bssid[3], bss->bssid[4], bss->bssid[5],
               bss->channel, bss->rssi);
    }

    free(info);
}
  • Up0
  • Down0
david_charlap
Join Date: 3 Apr 19
Posts: 17
Posted: Fri, 2019-05-17 05:14

Just to make it clear, I still can't connect to a WLAN.  I can scan for abailable APs, but when I try to connect to one, the callback function is never called.

My problem has not yet been solved and I still could use some assistance here.

  • Up0
  • Down0
c_rpedad
Profile picture
Join Date: 18 Jun 18
Location: San Jose
Posts: 317
Posted: Wed, 2019-06-05 15:50
The issue appears to be with Printf() function that has a 1K buffer as a local variable. It must be overflowing the stack of the WLAN thread. When changed that buffer to be static, it stopped crashing and rest of the app work.
  • Up0
  • Down0
david_charlap
Join Date: 3 Apr 19
Posts: 17
Posted: Thu, 2019-06-06 05:33

Yes.  Thank you for helping me solve this problem.  For others who may need the capability, here's my Printf function - the version that works.  It makes the buffer static and adds a mutex to make it thread-safe.  I first call setup_utilities() at application startup (in Initialize_Demo()) to create the mutex, then use Printf() where I need:

In its header file:

void setup_utilities(void);

int Printf(const char *format, ...)
    __attribute__ ((format (printf, 1, 2)));

 

And in the .c file:

static qurt_mutex_t mutex;

void setup_utilities(void) {
    qurt_mutex_create(&mutex);
}

int Printf(const char *format, ...) {
    va_list     args;
    int         len;
    static char buffer[1024];

    qurt_mutex_lock(&mutex);
    
    va_start(args, format);
    len = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    if (len > sizeof(buffer)) {
        len = sizeof(buffer) - 1;
    }

    PAL_Console_Write(len, buffer);

    qurt_mutex_unlock(&mutex);
    
    return len;
}
  • Up0
  • Down0
or Register

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries (“Qualcomm”). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.