blob: daf84279d6b88f731c7821c1b06565b4f32d4f58 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS 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 <cstdio>
#include <dlfcn.h>
#include <string.h>
#include <vector>
#include "base/basictypes.h"
#include "chromeos_cros_api.h" // NOLINT
#include "chromeos_network.h" // NOLINT
namespace chromeos { // NOLINT //
namespace {
// If set, points to a function provided by Chrome to add a histogram.
LibcrosTimeHistogramFunc addHistogram = NULL;
// Pointer to libcros (from ::dlopen call).
void* dll_handle = NULL;
}
class TimerInst {
public:
TimerInst(const char* name) {
if (addHistogram) {
name_ = std::string("Cros.") + name;
start_ = base::TimeTicks::Now();
}
}
~TimerInst() {
if (addHistogram) {
base::TimeDelta delta = base::TimeTicks::Now() - start_;
addHistogram(name_.c_str(), delta);
}
}
private:
std::string name_;
base::TimeTicks start_;
};
// Declare Function. These macros are used to define the imported functions
// from libcros. They will declare the proper type and define an exported
// variable to be used to call the function.
// |name| is the name of the function.
// |ret| is the return type.
// |arg[1-5]| are the types are the arguments.
// These are compile time declarations only.
// INIT_FUNC(name) needs to be called at runtime.
#define DECL_FUNC_0(name, ret) \
typedef ret (*name##Type)(); \
name##Type name = 0; \
ret WrapChromeOS##name() { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(); }
#define DECL_FUNC_1(name, ret, arg1) \
typedef ret (*name##Type)(arg1); \
name##Type name = 0; \
ret WrapChromeOS##name(arg1 a1) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1); }
#define DECL_FUNC_2(name, ret, arg1, arg2) \
typedef ret (*name##Type)(arg1, arg2); \
name##Type name = 0; \
ret WrapChromeOS##name(arg1 a1, arg2 a2) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1, a2); }
#define DECL_FUNC_3(name, ret, arg1, arg2, arg3) \
typedef ret (*name##Type)(arg1, arg2, arg3); \
name##Type name = 0; \
ret WrapChromeOS##name(arg1 a1, arg2 a2, arg3 a3) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1, a2, a3); }
#define DECL_FUNC_4(name, ret, arg1, arg2, arg3, arg4) \
typedef ret (*name##Type)(arg1, arg2, arg3, arg4); \
name##Type name = 0; \
ret WrapChromeOS##name(arg1 a1, arg2 a2, arg3 a3, arg4 a4) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1, a2, a3, a4); }
#define DECL_FUNC_5(name, ret, arg1, arg2, arg3, arg4, arg5) \
typedef ret (*name##Type)(arg1, arg2, arg3, arg4, arg5); \
name##Type name = 0; \
extern "C" ret ChromeOS##name(arg1, arg2, arg3, arg4, arg5); \
ret WrapChromeOS##name( \
arg1 a1, arg2 a2, arg3 a3, arg4 a4, arg5 a5) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1, a2, a3, a4, a5); }
#define DECL_FUNC_6(name, ret, arg1, arg2, arg3, arg4, arg5, arg6) \
typedef ret (*name##Type)(arg1, arg2, arg3, arg4, arg5, arg6); \
name##Type name = 0; \
extern "C" ret ChromeOS##name(arg1, arg2, arg3, arg4, arg5, arg6); \
ret WrapChromeOS##name( \
arg1 a1, arg2 a2, arg3 a3, arg4 a4, arg5 a5, arg6 a6) { \
static name##Type func = name##Type(::dlsym(dll_handle, "ChromeOS"#name)); \
TimerInst timer(#name); return func(a1, a2, a3, a4, a5, a6); }
// Version
DECL_FUNC_1(CrosVersionCheck, bool, chromeos::CrosAPIVersion);
// Networking
DECL_FUNC_2(ActivateCellularModem, bool, const char*, const char*);
DECL_FUNC_3(SetNetworkServicePropertyGValue, void, const char*, const char*,
const GValue*);
DECL_FUNC_2(ClearNetworkServiceProperty, void, const char*, const char*);
DECL_FUNC_3(SetNetworkDevicePropertyGValue, void, const char*, const char*,
const GValue*);
DECL_FUNC_3(SetNetworkIPConfigPropertyGValue, void, const char*, const char*,
const GValue*);
DECL_FUNC_2(DeleteServiceFromProfile, void, const char*, const char*);
DECL_FUNC_1(RequestCellularDataPlanUpdate, void, const char*);
DECL_FUNC_2(MonitorNetworkManagerProperties, NetworkPropertiesMonitor,
MonitorPropertyGValueCallback, void*);
DECL_FUNC_3(MonitorNetworkServiceProperties, NetworkPropertiesMonitor,
MonitorPropertyGValueCallback, const char*, void*);
DECL_FUNC_3(MonitorNetworkDeviceProperties, NetworkPropertiesMonitor,
MonitorPropertyGValueCallback, const char*, void*);
DECL_FUNC_1(DisconnectNetworkPropertiesMonitor, void, NetworkPropertiesMonitor);
DECL_FUNC_2(MonitorCellularDataPlan, DataPlanUpdateMonitor,
MonitorDataPlanCallback, void*);
DECL_FUNC_1(DisconnectDataPlanUpdateMonitor, void, DataPlanUpdateMonitor);
DECL_FUNC_3(MonitorSMS, SMSMonitor, const char*, MonitorSMSCallback, void*);
DECL_FUNC_1(DisconnectSMSMonitor, void, SMSMonitor);
DECL_FUNC_3(RequestNetworkServiceConnect, void, const char*,
NetworkActionCallback, void *);
DECL_FUNC_2(RequestNetworkManagerProperties, void,
NetworkPropertiesGValueCallback, void*);
DECL_FUNC_3(RequestNetworkServiceProperties, void, const char*,
NetworkPropertiesGValueCallback, void*);
DECL_FUNC_3(RequestNetworkDeviceProperties, void, const char*,
NetworkPropertiesGValueCallback, void*);
DECL_FUNC_3(RequestNetworkProfileProperties, void, const char*,
NetworkPropertiesGValueCallback, void*);
DECL_FUNC_4(RequestNetworkProfileEntryProperties, void, const char*,
const char*, NetworkPropertiesGValueCallback, void*);
DECL_FUNC_4(RequestHiddenWifiNetworkProperties, void, const char*, const char*,
NetworkPropertiesGValueCallback, void*);
DECL_FUNC_5(RequestVirtualNetworkProperties, void, const char*, const char*,
const char*, NetworkPropertiesGValueCallback, void*);
DECL_FUNC_1(RequestRemoveNetworkService, void, const char*);
DECL_FUNC_1(RequestNetworkServiceDisconnect, void, const char*);
DECL_FUNC_1(RequestNetworkScan, void, const char*);
DECL_FUNC_2(RequestNetworkDeviceEnable, void, const char*, bool);
DECL_FUNC_5(RequestRequirePin, void, const char*, const char*, bool,
NetworkActionCallback, void*);
DECL_FUNC_4(RequestEnterPin, void, const char*, const char*,
NetworkActionCallback, void*);
DECL_FUNC_5(RequestUnblockPin, void, const char*, const char*, const char*,
NetworkActionCallback, void*);
DECL_FUNC_5(RequestChangePin, void, const char*, const char*, const char*,
NetworkActionCallback, void*);
DECL_FUNC_1(ProposeScan, void, const char*);
DECL_FUNC_4(RequestCellularRegister, void, const char*, const char*,
NetworkActionCallback, void*);
DECL_FUNC_1(SetOfflineMode, bool, bool);
DECL_FUNC_1(ListIPConfigs, IPConfigStatus*, const char*);
DECL_FUNC_2(AddIPConfig, bool, const char*, IPConfigType);
DECL_FUNC_1(RemoveIPConfig, bool, IPConfig*);
DECL_FUNC_1(FreeIPConfigStatus, void, IPConfigStatus*);
DECL_FUNC_0(GetDeviceNetworkList, DeviceNetworkList*);
DECL_FUNC_1(FreeDeviceNetworkList, void, DeviceNetworkList*);
DECL_FUNC_4(ConfigureService, void, const char*, const GHashTable*,
NetworkActionCallback, void*);
char const * const kCrosDefaultPath = "/opt/google/chrome/chromeos/libcros.so";
// Initializes the variable by looking up the function by |name|.
// This macro uses the variable 'handle' and 'error_string'.
#define INIT_FUNC(name) \
name = WrapChromeOS##name; \
if (!::dlsym(dll_handle, "ChromeOS"#name)) { \
error_string += "Couldn't load: "#name","; \
}
bool LoadLibcros(const char* path_to_libcros, std::string& error_string) {
error_string.clear();
if (!path_to_libcros) {
error_string = "path_to_libcros can't be NULL";
return false;
}
dll_handle = ::dlopen(path_to_libcros, RTLD_NOW);
if (dll_handle == NULL) {
error_string = "Couldn't load libcros from: ";
error_string += path_to_libcros;
error_string += " error: ";
error_string += dlerror();
return false;
}
INIT_FUNC(CrosVersionCheck);
if (!CrosVersionCheck) {
// error_string will already be set.
return false;
}
if (!CrosVersionCheck(chromeos::kCrosAPIVersion)) {
const int buf_size = sizeof(int)*8+1;
char buf[buf_size];
typedef int (*VersionFuncType)();
// These weren't exported from older copies of the library. It's not an
// error so we don't use INIT_FUNC()
VersionFuncType GetMinCrosVersion =
VersionFuncType(::dlsym(dll_handle, "ChromeOSGetMinCrosVersion"));
VersionFuncType GetCrosVersion =
VersionFuncType(::dlsym(dll_handle, "ChromeOSGetCrosVersion"));
error_string = "Incompatible libcros version. Client: ";
snprintf(buf, buf_size, "%d", chromeos::kCrosAPIVersion);
error_string += buf;
if (GetMinCrosVersion && GetCrosVersion) {
snprintf(buf, buf_size, "%d", GetMinCrosVersion());
error_string += " Min: ";
error_string += buf;
snprintf(buf, buf_size, "%d", GetCrosVersion());
error_string += " Max: ";
error_string += buf;
}
return false;
}
// Networking
INIT_FUNC(ActivateCellularModem);
INIT_FUNC(SetNetworkServicePropertyGValue);
INIT_FUNC(ClearNetworkServiceProperty);
INIT_FUNC(SetNetworkDevicePropertyGValue);
INIT_FUNC(SetNetworkIPConfigPropertyGValue);
INIT_FUNC(DeleteServiceFromProfile);
INIT_FUNC(RequestCellularDataPlanUpdate);
INIT_FUNC(MonitorNetworkManagerProperties);
INIT_FUNC(MonitorNetworkServiceProperties);
INIT_FUNC(MonitorNetworkDeviceProperties);
INIT_FUNC(DisconnectNetworkPropertiesMonitor);
INIT_FUNC(MonitorCellularDataPlan);
INIT_FUNC(DisconnectDataPlanUpdateMonitor);
INIT_FUNC(MonitorSMS);
INIT_FUNC(DisconnectSMSMonitor);
INIT_FUNC(RequestNetworkServiceConnect);
INIT_FUNC(RequestNetworkManagerProperties);
INIT_FUNC(RequestNetworkServiceProperties);
INIT_FUNC(RequestNetworkDeviceProperties);
INIT_FUNC(RequestNetworkProfileProperties);
INIT_FUNC(RequestNetworkProfileEntryProperties);
INIT_FUNC(RequestHiddenWifiNetworkProperties);
INIT_FUNC(RequestVirtualNetworkProperties);
INIT_FUNC(RequestRemoveNetworkService);
INIT_FUNC(RequestNetworkServiceDisconnect);
INIT_FUNC(RequestNetworkScan);
INIT_FUNC(RequestNetworkDeviceEnable);
INIT_FUNC(RequestRequirePin);
INIT_FUNC(RequestEnterPin);
INIT_FUNC(RequestUnblockPin);
INIT_FUNC(RequestChangePin);
INIT_FUNC(ProposeScan);
INIT_FUNC(RequestCellularRegister);
INIT_FUNC(SetOfflineMode);
INIT_FUNC(ListIPConfigs);
INIT_FUNC(AddIPConfig);
INIT_FUNC(RemoveIPConfig);
INIT_FUNC(FreeIPConfigStatus);
INIT_FUNC(GetDeviceNetworkList);
INIT_FUNC(FreeDeviceNetworkList);
INIT_FUNC(ConfigureService);
return error_string.empty();
}
void SetLibcrosTimeHistogramFunction(LibcrosTimeHistogramFunc func) {
addHistogram = func;
}
} // namespace chromeos