void DataReceived(BUrlRequest* request, const char* data, off_t position, ssize_t size) { if (request != fRequest) delete request; BHttpRequest* httpReq = dynamic_cast<BHttpRequest*>(request); if (httpReq != NULL) { const BHttpResult& httpRes = (const BHttpResult&)httpReq->Result(); int32 status = httpRes.StatusCode(); if (BHttpRequest::IsClientErrorStatusCode(status) || BHttpRequest::IsServerErrorStatusCode(status)) { fRunning = false; } else if (BHttpRequest::IsRedirectionStatusCode(status)) return; } _ReleaseInit(); fInputAdapter->Write(data, size); }
status_t BGeolocation::LocateSelf(float& latitude, float& longitude) { // Enumerate wifi network and build JSON message BNetworkRoster& roster = BNetworkRoster::Default(); uint32 interfaceCookie = 0; BNetworkInterface interface; BString query("{\n\t\"wifiAccessPoints\": ["); int32 count = 0; while (roster.GetNextInterface(&interfaceCookie, interface) == B_OK) { uint32 networkCookie = 0; wireless_network network; BNetworkDevice device(interface.Name()); // TODO is that the correct way to enumerate devices? while (device.GetNextNetwork(networkCookie, network) == B_OK) { if (count != 0) query += ','; count++; query += "\n\t\t{ \"macAddress\": \""; query += network.address.ToString().ToUpper(); query += "\", \"signalStrength\": "; query << (int)network.signal_strength; query += ", \"signalToNoiseRatio\": "; query << (int)network.noise_level; query += " }"; } } query += "\n\t]\n}\n"; // Check that we have enough data (we need at least 2 networks) if (count < 2) return B_DEVICE_NOT_FOUND; class GeolocationListener: public BUrlProtocolListener { public: virtual ~GeolocationListener() {}; void DataReceived(BUrlRequest*, const char* data, off_t position, ssize_t size) { result.WriteAt(position, data, size); } BMallocIO result; }; GeolocationListener listener; // Send Request (POST JSON message) BUrlRequest* request = BUrlProtocolRoster::MakeRequest(fService, &listener); if (request == NULL) return B_BAD_DATA; BHttpRequest* http = dynamic_cast<BHttpRequest*>(request); if (http == NULL) { delete request; return B_BAD_DATA; } http->SetMethod(B_HTTP_POST); BMemoryIO* io = new BMemoryIO(query.String(), query.Length()); http->AdoptInputData(io, query.Length()); status_t result = http->Run(); if (result < 0) { delete http; return result; } while (http->IsRunning()) snooze(10000); // Parse reply const BHttpResult& reply = (const BHttpResult&)http->Result(); if (reply.StatusCode() != 200) { delete http; return B_ERROR; } BMessage data; result = BJson::Parse(data, (char*)listener.result.Buffer()); delete http; if (result != B_OK) { return result; } BMessage location; result = data.FindMessage("location", &location); if (result != B_OK) return result; double lat, lon; result = location.FindDouble("lat", &lat); if (result == B_OK) result = location.FindDouble("lng", &lon); latitude = lat; longitude = lon; return result; }