none
CmAcquireConnection returns CMRE_CONNECTION_ACQUIRE_FAILED - help me manage network connections RRS feed

  • Question

  • Hi everyone,

    I'm developing an application that shows  available wifi network and allow to connect.

    I used the Connection Manager API but I don't know how to use it well.

    When the app is starting, It create session use CmCreateSession().

    Get availableNetworkList by Native Wifi APis (ex. WlanGetAvailableNetworkList())

    Select AP in list and insert detail information and make 'xml' and attempt to connect to it

    making new config code is..

    void WlanConnector::MakeConfigByXml( int index, WCHAR *key, wchar_t *xmlBuffer, CM_CONNECTION_CONFIG **ppConfig, DWORD *cbConfigSize)
    {

     CspWiFiSpecificInfo *pCspWiFiInfo;
     CM_CONNECTION_CONFIG *pConfig = NULL;
     int xmlBufferLen, ulConfig, ulXmlBuffer;
     DWORD reason = 0;

     swprintf(xmlBuffer,
     L"<?xml version=\"1.0\"?>\
    <WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">\
     <name>%s</name>\
     <SSIDConfig>\
      <SSID>\
       <name>%s</name>\
      </SSID>\
      <nonBroadcast>true</nonBroadcast>\
     </SSIDConfig>\
     <connectionType>ESS</connectionType>\
     <connectionMode>manual</connectionMode>\
     <autoSwitch>false</autoSwitch>\
     <MSM>\
      <security>\
       <authEncryption>\
        <authentication>%s</authentication>\
        <encryption>%s</encryption>\
        <useOneX>false</useOneX>\
       </authEncryption>\
       <sharedKey>\
        <keyType>passPhrase</keyType>\
        <protected>false</protected>\
        <keyMaterial>%s</keyMaterial>\
       </sharedKey>\
      </security>\
     </MSM>\
    </WLANProfile>",this->availableList[index].ssid,this->availableList[index].ssid,this->availableList[index].authAlgo,
    this->availableList[index].cipherAlgo,key);

    //index is selected index in listbox


     xmlBufferLen = wcslen(xmlBuffer);
     ulXmlBuffer = (xmlBufferLen + 1) * sizeof(WCHAR);
     ulConfig = offsetof(CM_CONNECTION_CONFIG, TypeSpecificInfo[0]) +  offsetof(CspWiFiSpecificInfo, DevConfigXml[0]) +  ulXmlBuffer;
     pConfig = (CM_CONNECTION_CONFIG*)LocalAlloc(LPTR, ulConfig);

     ////////////////////////////////// connection config //////////////////////////////////
     pConfig->Version = CM_CURRENT_VERSION;
     pConfig->fEnabled = TRUE;
     pConfig->ConnectBehavior = CMCB_ALWAYS_CONNECTED;
     pConfig->Type = CM_CSP_WIFI_TYPE;
     pConfig->cbTypeSpecificInfo = offsetof(CspWiFiSpecificInfo, DevConfigXml[0]) + ulXmlBuffer
     pConfig->AutoReconnect.
     //// Fill WiFi specific info.
     pCspWiFiInfo = (CspWiFiSpecificInfo*)&pConfig->TypeSpecificInfo[0];
     pCspWiFiInfo->Version = CSP_WIFI_SPECIFIC_INFO_VERSION;
     pCspWiFiInfo->InterfaceSpecific = TRUE;
     memcpy(&pCspWiFiInfo->InterfaceGuid, &this->interfaceGuid, sizeof(GUID));

     pCspWiFiInfo->cbUserDataOffset = ulXmlBuffer;
     pCspWiFiInfo->cbDevConfig = ulXmlBuffer;
     memcpy(&pCspWiFiInfo->DevConfigXml[0], xmlBuffer, pCspWiFiInfo->cbDevConfig);

     *ppConfig = pConfig;
     *cbConfigSize = ulConfig;

    }

    /////save config code is..

    DWORD WlanConnector::SaveConnectionConfig(WCHAR *szConnectionName, CM_CONNECTION_CONFIG *pConfig, DWORD cbConfigSize)
    {
        CM_RESULT result = CMRE_INSUFFICIENT_BUFFER;
        CM_CONFIG_CHANGE_HANDLE pUpdateHandle = NULL;
        CM_CONNECTION_CONFIG* pOldConfig = NULL;
        DWORD cbOldSize = 255, dwError = ERROR_SUCCESS;
      BOOL bExist = FALSE;
     UINT i;
     
     bExist = this->FindConnectionConfigs(szConnectionName);
     wcscpy(this->pszConnection, szConnectionName);

     if(!bExist)
     {
      result = CmAddConnectionConfig(szConnectionName, pConfig, cbConfigSize);
      HLOCAL ret = LocalFree(pConfig);
     }
     else
     {
            for (i=0; i< MAX_TRY_COUNT_FOR_INSUFFICIENT_BUFFER && result == CMRE_INSUFFICIENT_BUFFER; i++)
            {
                LocalFree(pOldConfig);
                pOldConfig = (CM_CONNECTION_CONFIG*)LocalAlloc(0, cbOldSize);
                if (!pOldConfig)
                {
                    dwError = GetLastError();
                }

                result = CmGetToUpdateConnectionConfig(szConnectionName, pOldConfig, &cbOldSize, &pUpdateHandle);
            }
            LocalFree(pOldConfig);

            if (result != CMRE_SUCCESS)
            {
                dwError = GetLastError();
            }

            result = CmUpdateConnectionConfig(pUpdateHandle, CMCO_IMMEDIATE_APPLY, pConfig, cbConfigSize);
            if (result != CMRE_SUCCESS)
            {
                dwError = GetLastError();
            }  
        }
     return dwError;
    }

    Then ... When saved config is in CMCS_DISCONNECTED state, call CmAcquireConnection.. success to connect.

    But.. If I attempt to connect to another AP in this situation. I don't know How to disconnect network already connected.

    I tried to connect in the same way, succeed saving new config for another network,

    but CmAcquireConnection returns CMRE_CONNECTION_ACQUIRE_FAILED.

    What sould I do something additionally?

    And I Think that CmReleaseConnection release(disconnect) connected network in present

    But.. It was not working like my thought.

    Please help me to solve this problem. your answer will be highly appreciated..

    Monday, March 23, 2015 12:22 PM

Answers

  • Hi,

    There is a lot to connection manager. Can you try CmDeleteConnectionConfig for deleting and then call MakeConfigByXML and SaveConnectionConfig with parameters for the newer connection.

    Regards,

    Balaji.

    • Marked as answer by SunHo Choi Tuesday, March 24, 2015 5:42 AM
    Tuesday, March 24, 2015 4:49 AM
  • Hi,

    If you don't want to disconnect but have two profiles with you, can you try using 

    CmGetFirstCandidateConnection and CmGetNextCandidateConnection to try and connect to another AP. I haven't tried this but you may give it a go.

    Regards,

    Balaji.

    • Marked as answer by SunHo Choi Tuesday, March 24, 2015 8:57 AM
    Tuesday, March 24, 2015 7:41 AM

All replies

  • Hi,

    There is a lot to connection manager. Can you try CmDeleteConnectionConfig for deleting and then call MakeConfigByXML and SaveConnectionConfig with parameters for the newer connection.

    Regards,

    Balaji.

    • Marked as answer by SunHo Choi Tuesday, March 24, 2015 5:42 AM
    Tuesday, March 24, 2015 4:49 AM
  • Thanks for reply

    I've tried that, It's working, But Deleting config looks unstable, just in my opinion.

    if there is no way, I should use that way.

    It's unusual that function's useless

    Anyway Thank you!

    Tuesday, March 24, 2015 5:40 AM
  • Hi,

    If you don't want to disconnect but have two profiles with you, can you try using 

    CmGetFirstCandidateConnection and CmGetNextCandidateConnection to try and connect to another AP. I haven't tried this but you may give it a go.

    Regards,

    Balaji.

    • Marked as answer by SunHo Choi Tuesday, March 24, 2015 8:57 AM
    Tuesday, March 24, 2015 7:41 AM
  • CM_RESULT AcquireConnection() { CM_CONNECTION_HANDLE hConnection = NULL; CM_CONNECTION_DETAILS *pDetails = NULL; CM_RESULT result; DWORD dwError; //if(wcslen(this->pszConnection) > 0) //there is already connected

    //{ // result = CmDeleteConnectionConfig(this->pszConnection); //커넥션 컨픽을 지워 연결끊음 // memset(this->pszConnection, 0, MAX_SSID_LENGTH); //} if (this->pszConnection[0] != '\0') { CM_CONNECTION_HANDLE hConnection = NULL; for (result =CmGetFirstCandidateConnection(this->hCMSession, NULL, CMSO_DEFAULT, &hConnection); result == CMRE_SUCCESS; result = CmGetNextCandidateConnection(this->hCMSession, &hConnection)) { dwError = this->GetConnectionDetailsByHandle(hConnection, &pDetails); // Connect the WiFi connection in configured order. if (memcmp(&pDetails->Type, &CM_CSP_WIFI_TYPE, sizeof(CM_CONNECTION_TYPE)) == 0) { if (wcscmp(pDetails->szName, this->pszConnection) == 0) { result = CmAcquireConnection(hConnection); if (CMRE_SUCCESS == result) { this->b_connecting = FALSE; } goto exit; } } if (pDetails) { LocalFree(pDetails); pDetails = NULL; } hConnection = NULL; } } exit: LocalFree(pDetails); return result; }

    I've used this code, but this was working as I want.

    And then I found some code below.

    #define WIFICPL_CM_PRIORITY (CM_PRIORITY_BACKGROUND_LOWEST + 0x90)

    ..

    CmSetPriority(this->hCMSession, WIFICPL_CM_PRIORITY);

    When connection manager session create, set the priority.. By doing that connection switching worked well.

    Maybe the problem comes from priority.

    Anyway, I dont understand ' CM_PRIORITY_BACKGROUND_LOWEST + 0x90 '.

    https://msdn.microsoft.com/en-us/library/gg158471.aspx 

    This page about parameter of CmSetPriority() from MSDN. If u konws that.. Can u explain a little please? :(

    Tuesday, March 24, 2015 8:57 AM
  • Hi,

    The priority thing is unclear but i can imagine a scenario e.g. a GUI or a command line app that tries more than one connection at a time. 

    By using CmSetPriority you could possibly prioritize the connection requests to connection manager.

    From the page you mentioned there seem to be 2 different priorities used. Background could be for GUI apps. If you are trying a command line based app why not try the CM_PRIORITY_USER_INTERACTIVE_LOWEST or HIGHEST.

    Regards,

    Balaji.

    Tuesday, March 24, 2015 9:30 AM
  • Hi

    Im developing app for GUI.

    When I was in trouble, I used 'CM_PRIORITY_BACKGROUND_LOWEST' for parameter.

    But found some code that use 'CM_PRIORITY_BACKGROUND_LOWEST + 0x90' for google

    It's working well, after changing parameter  'LOWEST'  to 'LOWEST' + 0x90.

    But I dont know what means 0x90. :(  It's not in availale parameter list..

    Tuesday, March 24, 2015 11:26 AM