shill: On Service::Connect, connect the modem device to the network.
Also, uncouple the DBusProperties signal callbacks from Modem to make the proxy
implementation more consistent with the other proxies.
BUG=chromium-os:18727
TEST=unit tests
Change-Id: Icdddea8d2a30803150f2a159fdc5a719e960f95d
Reviewed-on: http://gerrit.chromium.org/gerrit/5444
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index 5a26d75..2c56b9d 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -18,8 +18,6 @@
#include "shill/device.h"
#include "shill/device_info.h"
#include "shill/manager.h"
-#include "shill/modem_cdma_proxy_interface.h"
-#include "shill/modem_proxy_interface.h"
#include "shill/modem_simple_proxy_interface.h"
#include "shill/profile.h"
#include "shill/property_accessor.h"
@@ -32,6 +30,10 @@
namespace shill {
+const char Cellular::kConnectPropertyPhoneNumber[] = "number";
+const char Cellular::kPhoneNumberCDMA[] = "#777";
+const char Cellular::kPhoneNumberGSM[] = "*99#";
+
Cellular::Network::Network() {
dict_[flimflam::kStatusProperty] = "";
dict_[flimflam::kNetworkIdProperty] = "";
@@ -109,6 +111,7 @@
dbus_owner_(owner),
dbus_path_(path),
service_registered_(false),
+ task_factory_(this),
allow_roaming_(false),
prl_version_(0),
scanning_(false),
@@ -194,7 +197,7 @@
void Cellular::InitProxies() {
proxy_.reset(
- ProxyFactory::factory()->CreateModemProxy(dbus_path_, dbus_owner_));
+ ProxyFactory::factory()->CreateModemProxy(this, dbus_path_, dbus_owner_));
simple_proxy_.reset(
ProxyFactory::factory()->CreateModemSimpleProxy(
dbus_path_, dbus_owner_));
@@ -373,6 +376,36 @@
return type == Device::kCellular;
}
+void Cellular::Connect() {
+ VLOG(2) << __func__;
+ if (state_ == kStateConnected) {
+ return;
+ }
+ CHECK_EQ(kStateRegistered, state_);
+ DBusPropertiesMap properties;
+ const char *phone_number = NULL;
+ switch (type_) {
+ case kTypeGSM:
+ phone_number = kPhoneNumberGSM;
+ break;
+ case kTypeCDMA:
+ phone_number = kPhoneNumberCDMA;
+ break;
+ default: NOTREACHED();
+ }
+ properties[kConnectPropertyPhoneNumber].writer().append_string(phone_number);
+ // TODO(petkov): Setup apn and "home_only".
+
+ // Defer connect because we may be in a dbus-c++ callback.
+ dispatcher_->PostTask(
+ task_factory_.NewRunnableMethod(&Cellular::ConnectTask, properties));
+}
+
+void Cellular::ConnectTask(const DBusPropertiesMap &properties) {
+ VLOG(2) << __func__;
+ simple_proxy_->Connect(properties);
+}
+
void Cellular::OnCDMARegistrationStateChanged(uint32 state_1x,
uint32 state_evdo) {
CHECK_EQ(kTypeCDMA, type_);
@@ -386,6 +419,13 @@
HandleNewSignalQuality(strength);
}
+void Cellular::OnModemStateChanged(uint32 old_state,
+ uint32 new_state,
+ uint32 reason) {
+ // TODO(petkov): Implement this.
+ NOTIMPLEMENTED();
+}
+
Stringmaps Cellular::EnumerateNetworks() {
Stringmaps to_return;
for (vector<Network>::const_iterator it = found_networks_.begin();
diff --git a/cellular.h b/cellular.h
index 4f8efbf..dc9b00b 100644
--- a/cellular.h
+++ b/cellular.h
@@ -8,20 +8,23 @@
#include <string>
#include <base/basictypes.h>
+#include <base/task.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
+#include "shill/dbus_properties.h"
#include "shill/device.h"
#include "shill/modem_cdma_proxy_interface.h"
+#include "shill/modem_proxy_interface.h"
#include "shill/refptr_types.h"
#include "shill/shill_event.h"
namespace shill {
-class ModemProxyInterface;
class ModemSimpleProxyInterface;
class Cellular : public Device,
- public ModemCDMAProxyListener {
+ public ModemCDMAProxyListener,
+ public ModemProxyListener {
public:
enum Type {
kTypeGSM,
@@ -79,6 +82,8 @@
uint32 retries_left;
};
+ static const char kConnectPropertyPhoneNumber[];
+
// |owner| is the ModemManager DBus service owner (e.g., ":1.17"). |path| is
// the ModemManager.Modem DBus object path (e.g.,
// "/org/chromium/ModemManager/Gobi/0").
@@ -92,12 +97,19 @@
const std::string &path);
virtual ~Cellular();
+ // Asynchronously connects the modem to the network.
+ void Connect();
+
// Inherited from Device.
virtual void Start();
virtual void Stop();
virtual bool TechnologyIs(Technology type);
private:
+ static const char kPhoneNumberCDMA[];
+ static const char kPhoneNumberGSM[];
+
+ FRIEND_TEST(CellularTest, Connect);
FRIEND_TEST(CellularTest, GetCDMARegistrationState);
FRIEND_TEST(CellularTest, GetCDMASignalQuality);
FRIEND_TEST(CellularTest, GetModemInfo);
@@ -108,6 +120,8 @@
FRIEND_TEST(CellularTest, InitProxiesGSM);
FRIEND_TEST(CellularTest, Start);
+ void ConnectTask(const DBusPropertiesMap &properties);
+
Stringmaps EnumerateNetworks();
StrIntPair SimLockStatusToProperty();
void HelpRegisterDerivedStringmaps(const std::string &name,
@@ -155,11 +169,16 @@
// device |state_|.
bool IsModemRegistered();
- // Signal callbacks from ModemCDMAProxyListener.
+ // Signal callbacks inherited from ModemCDMAProxyListener.
virtual void OnCDMARegistrationStateChanged(uint32 state_1x,
uint32 state_evdo);
virtual void OnCDMASignalQualityChanged(uint32 strength);
+ // Signal callbacks inherited from ModemProxyListener.
+ virtual void OnModemStateChanged(uint32 old_state,
+ uint32 new_state,
+ uint32 reason);
+
Type type_;
State state_;
@@ -174,6 +193,8 @@
CellularServiceRefPtr service_;
bool service_registered_;
+ ScopedRunnableMethodFactory<Cellular> task_factory_;
+
// Properties
bool allow_roaming_;
std::string carrier_;
diff --git a/cellular_service.cc b/cellular_service.cc
index 3685ccd..cbe9e02 100644
--- a/cellular_service.cc
+++ b/cellular_service.cc
@@ -10,15 +10,11 @@
#include <chromeos/dbus/service_constants.h>
#include "shill/cellular.h"
-#include "shill/control_interface.h"
-#include "shill/device.h"
-#include "shill/device_info.h"
-#include "shill/manager.h"
-#include "shill/shill_event.h"
using std::string;
namespace shill {
+
CellularService::CellularService(ControlInterface *control_interface,
EventDispatcher *dispatcher,
Manager *manager,
@@ -48,7 +44,9 @@
CellularService::~CellularService() { }
-void CellularService::Connect() { }
+void CellularService::Connect() {
+ cellular_->Connect();
+}
void CellularService::Disconnect() { }
diff --git a/cellular_service.h b/cellular_service.h
index ad39dab..f1b2c0a 100644
--- a/cellular_service.h
+++ b/cellular_service.h
@@ -11,7 +11,6 @@
#include <base/basictypes.h>
#include "shill/refptr_types.h"
-#include "shill/shill_event.h"
#include "shill/service.h"
namespace shill {
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index 26f9eec..0e5e0f3 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -29,7 +29,7 @@
cdma_proxy_(new MockModemCDMAProxy()),
proxy_factory_(this),
device_(new Cellular(&control_interface_,
- NULL,
+ &dispatcher_,
&manager_,
"usb0",
3,
@@ -52,7 +52,8 @@
public:
TestProxyFactory(CellularTest *test) : test_(test) {}
- virtual ModemProxyInterface *CreateModemProxy(const string &path,
+ virtual ModemProxyInterface *CreateModemProxy(ModemProxyListener *listener,
+ const string &path,
const string &service) {
return test_->proxy_.release();
}
@@ -247,4 +248,28 @@
EXPECT_EQ(kStrength, device_->service_->strength());
}
+namespace {
+
+MATCHER(ContainsPhoneNumber, "") {
+ return ContainsKey(arg, Cellular::kConnectPropertyPhoneNumber);
+}
+
+} // namespace {}
+
+TEST_F(CellularTest, Connect) {
+ device_->state_ = Cellular::kStateConnected;
+ device_->Connect();
+
+ device_->state_ = Cellular::kStateRegistered;
+ device_->Connect();
+ ASSERT_FALSE(device_->task_factory_.empty());
+
+ DBusPropertiesMap properties;
+ properties[Cellular::kConnectPropertyPhoneNumber].writer().append_string(
+ Cellular::kPhoneNumberGSM);
+ EXPECT_CALL(*simple_proxy_, Connect(ContainsPhoneNumber())).Times(1);
+ device_->simple_proxy_.reset(simple_proxy_.release());
+ dispatcher_.DispatchPendingEvents();
+}
+
} // namespace shill
diff --git a/dbus_properties_proxy.cc b/dbus_properties_proxy.cc
index 6f43fbc..c8a19e3 100644
--- a/dbus_properties_proxy.cc
+++ b/dbus_properties_proxy.cc
@@ -6,18 +6,16 @@
#include <base/logging.h>
-#include "shill/modem.h"
-
namespace shill {
using std::string;
using std::vector;
-DBusPropertiesProxy::DBusPropertiesProxy(DBus::Connection *connection,
- Modem *modem,
+DBusPropertiesProxy::DBusPropertiesProxy(DBusPropertiesProxyListener *listener,
+ DBus::Connection *connection,
const string &path,
const string &service)
- : proxy_(connection, modem, path, service) {}
+ : proxy_(listener, connection, path, service) {}
DBusPropertiesProxy::~DBusPropertiesProxy() {}
@@ -25,26 +23,29 @@
return proxy_.GetAll(interface_name);
}
-DBusPropertiesProxy::Proxy::Proxy(DBus::Connection *connection,
- Modem *modem,
+DBusPropertiesProxy::Proxy::Proxy(DBusPropertiesProxyListener *listener,
+ DBus::Connection *connection,
const string &path,
const string &service)
: DBus::ObjectProxy(*connection, path, service.c_str()),
- modem_(modem) {}
+ listener_(listener) {}
DBusPropertiesProxy::Proxy::~Proxy() {}
void DBusPropertiesProxy::Proxy::MmPropertiesChanged(
const string &interface,
const DBusPropertiesMap &properties) {
- LOG(INFO) << "MmPropertiesChanged: " << interface;
+ VLOG(2) << __func__ << "(" << interface << ")";
+ listener_->OnModemManagerPropertiesChanged(interface, properties);
}
void DBusPropertiesProxy::Proxy::PropertiesChanged(
const string &interface,
const DBusPropertiesMap &changed_properties,
const vector<string> &invalidated_properties) {
- LOG(INFO) << "PropertiesChanged: " << interface;
+ VLOG(2) << __func__ << "(" << interface << ")";
+ listener_->OnDBusPropertiesChanged(
+ interface, changed_properties, invalidated_properties);
}
} // namespace shill
diff --git a/dbus_properties_proxy.h b/dbus_properties_proxy.h
index f3ab239..8bf474b 100644
--- a/dbus_properties_proxy.h
+++ b/dbus_properties_proxy.h
@@ -12,12 +12,10 @@
namespace shill {
-class Modem;
-
class DBusPropertiesProxy : public DBusPropertiesProxyInterface {
public:
- DBusPropertiesProxy(DBus::Connection *connection,
- Modem *modem,
+ DBusPropertiesProxy(DBusPropertiesProxyListener *listener,
+ DBus::Connection *connection,
const std::string &path,
const std::string &service);
virtual ~DBusPropertiesProxy();
@@ -29,8 +27,8 @@
class Proxy : public org::freedesktop::DBus::Properties_proxy,
public DBus::ObjectProxy {
public:
- Proxy(DBus::Connection *connection,
- Modem *modem,
+ Proxy(DBusPropertiesProxyListener *listener,
+ DBus::Connection *connection,
const std::string &path,
const std::string &service);
virtual ~Proxy();
@@ -45,7 +43,7 @@
const DBusPropertiesMap &changed_properties,
const std::vector<std::string> &invalidated_properties);
- Modem *modem_;
+ DBusPropertiesProxyListener *listener_;
DISALLOW_COPY_AND_ASSIGN(Proxy);
};
diff --git a/dbus_properties_proxy_interface.h b/dbus_properties_proxy_interface.h
index 7aeea03..93320dc 100644
--- a/dbus_properties_proxy_interface.h
+++ b/dbus_properties_proxy_interface.h
@@ -5,6 +5,8 @@
#ifndef SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
#define SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
+#include <vector>
+
#include "shill/dbus_properties.h"
namespace shill {
@@ -18,6 +20,21 @@
virtual DBusPropertiesMap GetAll(const std::string &interface_name) = 0;
};
+// DBus.Properties signal listener to be associated with the proxy.
+class DBusPropertiesProxyListener {
+ public:
+ virtual ~DBusPropertiesProxyListener() {}
+
+ virtual void OnDBusPropertiesChanged(
+ const std::string &interface,
+ const DBusPropertiesMap &changed_properties,
+ const std::vector<std::string> &invalidated_properties) = 0;
+
+ virtual void OnModemManagerPropertiesChanged(
+ const std::string &interface,
+ const DBusPropertiesMap &properties) = 0;
+};
+
} // namespace shill
#endif // SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
diff --git a/mock_modem_simple_proxy.h b/mock_modem_simple_proxy.h
index f0ba0a2..b5877df 100644
--- a/mock_modem_simple_proxy.h
+++ b/mock_modem_simple_proxy.h
@@ -14,6 +14,7 @@
class MockModemSimpleProxy : public ModemSimpleProxyInterface {
public:
MOCK_METHOD0(GetStatus, DBusPropertiesMap());
+ MOCK_METHOD1(Connect, void(const DBusPropertiesMap &properties));
};
} // namespace shill
diff --git a/modem.cc b/modem.cc
index 87e3d3e..8e15156 100644
--- a/modem.cc
+++ b/modem.cc
@@ -13,6 +13,7 @@
#include "shill/rtnl_handler.h"
using std::string;
+using std::vector;
namespace shill {
@@ -122,4 +123,18 @@
}
}
+void Modem::OnDBusPropertiesChanged(
+ const string &interface,
+ const DBusPropertiesMap &changed_properties,
+ const vector<string> &invalidated_properties) {
+ // Ignored.
+}
+
+void Modem::OnModemManagerPropertiesChanged(
+ const string &interface,
+ const DBusPropertiesMap &properties) {
+ // TODO(petkov): Implement this.
+ NOTIMPLEMENTED();
+}
+
} // namespace shill
diff --git a/modem.h b/modem.h
index e3e5f67..78a1e97 100644
--- a/modem.h
+++ b/modem.h
@@ -23,7 +23,7 @@
// Handles an instance of ModemManager.Modem and an instance of a Cellular
// device.
-class Modem {
+class Modem : public DBusPropertiesProxyListener {
public:
// |owner| is the ModemManager DBus service owner (e.g., ":1.17"). |path| is
// the ModemManager.Modem DBus object path (e.g.,
@@ -35,7 +35,8 @@
Manager *manager);
~Modem();
- // Initializes support for the modem, possibly constructing a Cellular device.
+ // Asynchronously initializes support for the modem, possibly constructing a
+ // Cellular device.
void Init();
private:
@@ -59,6 +60,15 @@
// properties are invalid.
void CreateCellularDevice(const DBusPropertiesMap &properties);
+ // Signal callbacks inherited from DBusPropertiesProxyListener.
+ virtual void OnDBusPropertiesChanged(
+ const std::string &interface,
+ const DBusPropertiesMap &changed_properties,
+ const std::vector<std::string> &invalidated_properties);
+ virtual void OnModemManagerPropertiesChanged(
+ const std::string &interface,
+ const DBusPropertiesMap &properties);
+
// A proxy to the org.freedesktop.DBus.Properties interface used to obtain
// ModemManager.Modem properties and watch for property changes.
scoped_ptr<DBusPropertiesProxyInterface> dbus_properties_proxy_;
diff --git a/modem_proxy.cc b/modem_proxy.cc
index 3328667..1eb1b0c 100644
--- a/modem_proxy.cc
+++ b/modem_proxy.cc
@@ -10,10 +10,11 @@
namespace shill {
-ModemProxy::ModemProxy(DBus::Connection *connection,
+ModemProxy::ModemProxy(ModemProxyListener *listener,
+ DBus::Connection *connection,
const string &path,
const string &service)
- : proxy_(connection, path, service) {}
+ : proxy_(listener, connection, path, service) {}
ModemProxy::~ModemProxy() {}
@@ -25,19 +26,20 @@
return proxy_.GetInfo();
}
-ModemProxy::Proxy::Proxy(DBus::Connection *connection,
+ModemProxy::Proxy::Proxy(ModemProxyListener *listener,
+ DBus::Connection *connection,
const string &path,
const string &service)
- : DBus::ObjectProxy(*connection, path, service.c_str()) {}
+ : DBus::ObjectProxy(*connection, path, service.c_str()),
+ listener_(listener) {}
ModemProxy::Proxy::~Proxy() {}
void ModemProxy::Proxy::StateChanged(const uint32 &old,
const uint32 &_new,
const uint32 &reason) {
- VLOG(2) << __func__;
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ VLOG(2) << __func__ << "(" << old << ", " << _new << ", " << reason << ")";
+ listener_->OnModemStateChanged(old, _new, reason);
}
} // namespace shill
diff --git a/modem_proxy.h b/modem_proxy.h
index a1300b8..4a1a40d 100644
--- a/modem_proxy.h
+++ b/modem_proxy.h
@@ -12,11 +12,13 @@
namespace shill {
-// There's a single proxy per ModemManager.Modem service identified by its DBus
-// |path| and owner name |service|.
+// A proxy to ModemManager.Modem.
class ModemProxy : public ModemProxyInterface {
public:
- ModemProxy(DBus::Connection *connection,
+ // Constructs a ModemManager.Modem DBus object proxy at |path| owned by
+ // |service|. Caught signals will be dispatched to |listener|.
+ ModemProxy(ModemProxyListener *listener,
+ DBus::Connection *connection,
const std::string &path,
const std::string &service);
virtual ~ModemProxy();
@@ -29,7 +31,8 @@
class Proxy : public org::freedesktop::ModemManager::Modem_proxy,
public DBus::ObjectProxy {
public:
- Proxy(DBus::Connection *connection,
+ Proxy(ModemProxyListener *listener,
+ DBus::Connection *connection,
const std::string &path,
const std::string &service);
virtual ~Proxy();
@@ -40,6 +43,8 @@
const uint32 &_new,
const uint32 &reason);
+ ModemProxyListener *listener_;
+
DISALLOW_COPY_AND_ASSIGN(Proxy);
};
diff --git a/modem_proxy_interface.h b/modem_proxy_interface.h
index 52e2d48..2616dea 100644
--- a/modem_proxy_interface.h
+++ b/modem_proxy_interface.h
@@ -21,6 +21,16 @@
virtual Info GetInfo() = 0;
};
+// ModemManager.Modem signal listener to be associated with the proxy.
+class ModemProxyListener {
+ public:
+ virtual ~ModemProxyListener() {}
+
+ virtual void OnModemStateChanged(uint32 old_state,
+ uint32 new_state,
+ uint32 reason) = 0;
+};
+
} // namespace shill
#endif // SHILL_MODEM_PROXY_INTERFACE_
diff --git a/modem_simple_proxy.cc b/modem_simple_proxy.cc
index a8b48b1..37c9c83 100644
--- a/modem_simple_proxy.cc
+++ b/modem_simple_proxy.cc
@@ -19,6 +19,10 @@
return proxy_.GetStatus();
}
+void ModemSimpleProxy::Connect(const DBusPropertiesMap &properties) {
+ proxy_.Connect(properties);
+}
+
ModemSimpleProxy::Proxy::Proxy(DBus::Connection *connection,
const string &path,
const string &service)
diff --git a/modem_simple_proxy.h b/modem_simple_proxy.h
index 91fccd2..9d62ead 100644
--- a/modem_simple_proxy.h
+++ b/modem_simple_proxy.h
@@ -22,6 +22,7 @@
// Inherited from ModemSimpleProxyInterface.
virtual DBusPropertiesMap GetStatus();
+ virtual void Connect(const DBusPropertiesMap &properties);
private:
class Proxy : public org::freedesktop::ModemManager::Modem::Simple_proxy,
diff --git a/modem_simple_proxy_interface.h b/modem_simple_proxy_interface.h
index 9d0c248..fbf32c6 100644
--- a/modem_simple_proxy_interface.h
+++ b/modem_simple_proxy_interface.h
@@ -16,6 +16,7 @@
virtual ~ModemSimpleProxyInterface() {}
virtual DBusPropertiesMap GetStatus() = 0;
+ virtual void Connect(const DBusPropertiesMap &properties) = 0;
};
} // namespace shill
diff --git a/modem_unittest.cc b/modem_unittest.cc
index 4a4b23d..963365c 100644
--- a/modem_unittest.cc
+++ b/modem_unittest.cc
@@ -60,7 +60,7 @@
TestProxyFactory(ModemTest *test) : test_(test) {}
virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
- Modem *modem,
+ DBusPropertiesProxyListener *listener,
const string &path,
const string &service) {
return test_->proxy_.release();
diff --git a/proxy_factory.cc b/proxy_factory.cc
index 2e90348..c5191c6 100644
--- a/proxy_factory.cc
+++ b/proxy_factory.cc
@@ -32,10 +32,10 @@
}
DBusPropertiesProxyInterface *ProxyFactory::CreateDBusPropertiesProxy(
- Modem *modem,
+ DBusPropertiesProxyListener *listener,
const string &path,
const string &service) {
- return new DBusPropertiesProxy(connection(), modem, path, service);
+ return new DBusPropertiesProxy(listener, connection(), path, service);
}
ModemManagerProxyInterface *ProxyFactory::CreateModemManagerProxy(
@@ -45,9 +45,11 @@
return new ModemManagerProxy(connection(), manager, path, service);
}
-ModemProxyInterface *ProxyFactory::CreateModemProxy(const string &path,
- const string &service) {
- return new ModemProxy(connection(), path, service);
+ModemProxyInterface *ProxyFactory::CreateModemProxy(
+ ModemProxyListener *listener,
+ const string &path,
+ const string &service) {
+ return new ModemProxy(listener, connection(), path, service);
}
ModemSimpleProxyInterface *ProxyFactory::CreateModemSimpleProxy(
diff --git a/proxy_factory.h b/proxy_factory.h
index 0fc1cbd..777051a 100644
--- a/proxy_factory.h
+++ b/proxy_factory.h
@@ -16,13 +16,14 @@
namespace shill {
class DBusPropertiesProxyInterface;
+class DBusPropertiesProxyListener;
class DHCPProxyInterface;
-class Modem;
class ModemCDMAProxyInterface;
class ModemCDMAProxyListener;
class ModemManager;
class ModemManagerProxyInterface;
class ModemProxyInterface;
+class ModemProxyListener;
class ModemSimpleProxyInterface;
class SupplicantInterfaceProxyInterface;
class SupplicantProcessProxyInterface;
@@ -36,7 +37,7 @@
void Init();
virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
- Modem *modem,
+ DBusPropertiesProxyListener *listener,
const std::string &path,
const std::string &service);
@@ -45,7 +46,8 @@
const std::string &path,
const std::string &service);
- virtual ModemProxyInterface *CreateModemProxy(const std::string &path,
+ virtual ModemProxyInterface *CreateModemProxy(ModemProxyListener *listener,
+ const std::string &path,
const std::string &service);
virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(