user3344429
user3344429

Reputation: 160

NEHotspotHelper: Not Able to Send Web Request in Authenticating State of Authentication State Machine

I have implemented the NEHotspotHelper so that I can perform authentication in the background for networks with a captive portal.

I need to perform a web request in the 'authenticating' state so that I can retrieve the Wispr and also access an API.

However, when I try to use URLSession to send a web request, the request fails. This is the error:

[594:88737] dnssd_clientstub read_all(7) DEFUNCT
[594:88783] TIC TCP Conn Failed [4:0x1c0177a00]: 12:8 Err(-65554)
[594:88783] Task <FFD0DAE6-4864-437D-94F2-C9ED5D5748E2>.<1> HTTP load failed (error code: -1003 [12:8])
[594:88783] Task <FFD0DAE6-4864-437D-94F2-C9ED5D5748E2>.<1> finished with error - code: -1003

See a snippet of my code:


 let registered = NEHotspotHelper.register(options: options, queue: queue) { (cmd: NEHotspotHelperCommand) in
    print("Received command: \(cmd.commandType.rawValue)")
    if cmd.commandType == NEHotspotHelperCommandType.filterScanList {
        //Get all available hotspots
        print("filter scan list")
        var list: [NEHotspotNetwork] = cmd.networkList!
        var response: NEHotspotHelperResponse
        for l in list {
            if (l.ssid=="my-ssid") {
                response = cmd.createResponse(NEHotspotHelperResult.success)
            } else {
                response = cmd.createResponse(NEHotspotHelperResult.failure)                       
            }
            response.setNetworkList([chosenNetwork])
            response.deliver()
        }   
    } else if cmd.commandType == NEHotspotHelperCommandType.evaluate {
        if let network = cmd.network {            
            if (network.ssid=="my-ssid") {            
                network.setConfidence(NEHotspotHelperConfidence.high)
                let response = cmd.createResponse(NEHotspotHelperResult.success)
                response.setNetwork(network)                 
                response.deliver() //Respond back
            } else {
                let response = cmd.createResponse(NEHotspotHelperResult.failure)
                response.deliver()
            }
        }
    } else if cmd.commandType == NEHotspotHelperCommandType.authenticate {
        print("authenticate")
        var response = cmd.createResponse(NEHotspotHelperResult.unsupportedNetwork)
        if let network = cmd.network{
            if network.ssid == "my-ssid"{
                self.queryUrl()
                response = cmd.createResponse(NEHotspotHelperResult.success)
            }
        }
        response.deliver() //Respond back                    
    }
}

func queryUrl(){
    let config = URLSessionConfiguration.default
    config.allowsCellularAccess = false;

    let session = URLSession.init(configuration: config)

    let url = URL(string: "https://172.217.20.35")

    let semaphore = DispatchSemaphore(value: 0)
    let task = session.dataTask(with: url!){(data, response, error) in
        if  data==nil {
            print(data as Any)            
        }
        else{
            print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue) as Any)
        }
        semaphore.signal()
    }

    task.resume()
    _ = semaphore.wait(timeout: .distantFuture)    
}

Upvotes: 3

Views: 1005

Answers (3)

Muhammad Zeeshan
Muhammad Zeeshan

Reputation: 2451

I was also facing the similar issue. However, I found that developer need to bind the request with the received command before making web request to the connected network. All you need to do is to make NSMutableURLRequest and then call hitTestURLRequest.bind(to: command) because bind function is defined in the category of NSMutableURLRequest.

Upvotes: 1

Pierre
Pierre

Reputation: 9052

This is the just of it:

if cmd.commandType
    filterScanList
        - SetConfidence to each of your networks in cmd.networkList - High and add to a local list variable.
        - create Response.Success
        - set Response.NetworkList to your list of confident networks
        ----
        - deliver Response
    Evaluate or PresentUI
        //If it's your network
        - SetConfidence to cmd.network - High
        - create Response.Success
        - set Response.Network to cmd.network
        //If it's not your network
        - create Response.UnsupportedNetwork
        ----
        - deliver Response
    Authenticate or Maintain
        //If it's your network
        - SetConfidence to cmd.network - High
        - create Response.Success
        - set Response.Network to cmd.network
        - TRY AUTHENTICATE HERE SYNCHRONOUSLY
        //If it's not your network
        - create Response.UnsupportedNetwork
        ----
        - deliver Response
    Logoff or None
        - create Response.Success
        ----
        - deliver Response

Upvotes: 0

RajV
RajV

Reputation: 7180

Others have reported problem with name server resolution from NEHotspotHelper callback. Try using an IP address to make the call.

Also don't forget URLSession works asynchronously. You will need to call response.deliver() only after the web service calls finishes.

Upvotes: 0

Related Questions