| Index: native_client_sdk/src/examples/api/vpn_provider/vpn_provider_helper.cc
|
| diff --git a/native_client_sdk/src/examples/api/vpn_provider/vpn_provider_helper.cc b/native_client_sdk/src/examples/api/vpn_provider/vpn_provider_helper.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..455d9d0d5141c9d790d91d64ff7e91a6b08186b4
|
| --- /dev/null
|
| +++ b/native_client_sdk/src/examples/api/vpn_provider/vpn_provider_helper.cc
|
| @@ -0,0 +1,128 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "vpn_provider_helper.h"
|
| +
|
| +#include <sstream>
|
| +
|
| +#include "ppapi/cpp/var_dictionary.h"
|
| +
|
| +VpnProviderHelper::VpnProviderHelper(pp::Instance* instance)
|
| + : instance_(instance),
|
| + thread_(pp::InstanceHandle(instance)),
|
| + vpn_(pp::InstanceHandle(instance)),
|
| + factory_(this),
|
| + send_packet_pending_(false) {
|
| + thread_.Start();
|
| +}
|
| +
|
| +void VpnProviderHelper::Init() {
|
| + thread_.message_loop().PostWork(
|
| + factory_.NewCallback(&VpnProviderHelper::InitOnThread));
|
| +}
|
| +
|
| +void VpnProviderHelper::Bind(const std::string& config,
|
| + const std::string& name) {
|
| + thread_.message_loop().PostWork(
|
| + factory_.NewCallback(&VpnProviderHelper::BindOnThread, config, name));
|
| +}
|
| +
|
| +void VpnProviderHelper::SendPacket(const pp::Var& data) {
|
| + thread_.message_loop().PostWork(
|
| + factory_.NewCallback(&VpnProviderHelper::SendPacketOnThread, data));
|
| +}
|
| +
|
| +void VpnProviderHelper::InitOnThread(int32_t result) {
|
| + instance_->PostMessage("NaCl: VpnProviderHelper::InitOnThread()");
|
| + if (!vpn_.IsAvailable()) {
|
| + instance_->PostMessage(
|
| + "NaCl: VpnProviderHelper::InitOnThread(): "
|
| + "VpnProvider interface not available!");
|
| + }
|
| +
|
| + // Initial Callback registration
|
| + vpn_.ReceivePacket(factory_.NewCallbackWithOutput(
|
| + &VpnProviderHelper::ReceivePacketCompletionCallback));
|
| +}
|
| +
|
| +void VpnProviderHelper::BindOnThread(int32_t result,
|
| + const std::string& config,
|
| + const std::string& name) {
|
| + instance_->PostMessage("NaCl: VpnProviderHelper::BindOnThread()");
|
| +
|
| + vpn_.Bind(config, name,
|
| + factory_.NewCallback(&VpnProviderHelper::BindCompletionCallback));
|
| +}
|
| +
|
| +void VpnProviderHelper::SendPacketOnThread(int32_t result,
|
| + const pp::Var& data) {
|
| + if (!send_packet_pending_) {
|
| + send_packet_pending_ = true;
|
| + vpn_.SendPacket(
|
| + data,
|
| + factory_.NewCallback(&VpnProviderHelper::SendPacketCompletionCallback));
|
| + } else {
|
| + std::stringstream ss;
|
| + ss << "NaCl: VpnProviderHelper::SendPacketOnThread: "
|
| + << "Queueing Packet";
|
| + instance_->PostMessage(ss.str());
|
| +
|
| + send_packet_queue_.push(data);
|
| + }
|
| +}
|
| +
|
| +void VpnProviderHelper::BindCompletionCallback(int32_t result) {
|
| + std::stringstream ss;
|
| + ss << "NaCl: VpnProviderHelper::BindCompletionCallback(" << result << ")";
|
| + instance_->PostMessage(ss.str());
|
| +
|
| + pp::VarDictionary dict;
|
| + dict.Set("cmd", "bindSuccess");
|
| + instance_->PostMessage(dict);
|
| +}
|
| +
|
| +void VpnProviderHelper::ReceivePacketCompletionCallback(int32_t result,
|
| + const pp::Var& packet) {
|
| + std::stringstream ss;
|
| + ss << "NaCl: VpnProviderHelper::ReceivePacketCompletionCallback(" << result
|
| + << ")";
|
| + instance_->PostMessage(ss.str());
|
| +
|
| + /* This is the place where the developer would unpack the packet from the
|
| + * pp:Var and send it the their implementation. Example code below.
|
| + *
|
| + * pp::VarDictionary message;
|
| + * message.Set("operation", "write");
|
| + * message.Set("payload", packet);
|
| + * SendMessageToTun((struct PP_Var*)&message.pp_var());
|
| + */
|
| +
|
| + // Re-register callback
|
| + if (result == PP_OK) {
|
| + vpn_.ReceivePacket(factory_.NewCallbackWithOutput(
|
| + &VpnProviderHelper::ReceivePacketCompletionCallback));
|
| + }
|
| +}
|
| +
|
| +void VpnProviderHelper::SendPacketCompletionCallback(int32_t result) {
|
| + std::stringstream ss;
|
| + ss << "NaCl: VpnProviderHelper::SendPacketCompletionCallback(" << result
|
| + << ")";
|
| + instance_->PostMessage(ss.str());
|
| +
|
| + // If we have queued packets send them before accepting new ones
|
| + if (!send_packet_queue_.empty()) {
|
| + std::stringstream ss;
|
| + ss << "NaCl: VpnProviderHelper::SendPacketCompletionCallback: "
|
| + << "Sending queued packed.";
|
| + instance_->PostMessage(ss.str());
|
| +
|
| + vpn_.SendPacket(
|
| + send_packet_queue_.front(),
|
| + factory_.NewCallback(&VpnProviderHelper::SendPacketCompletionCallback));
|
| + send_packet_queue_.pop();
|
| + } else {
|
| + send_packet_pending_ = false;
|
| + }
|
| +}
|
|
|