diff options
-rw-r--r-- | addons/kodi.binary.global.network/addon.xml.in | 7 | ||||
-rw-r--r-- | system/addon-manifest.xml | 1 | ||||
-rw-r--r-- | xbmc/addons/AddonDll.cpp | 3 | ||||
-rw-r--r-- | xbmc/addons/interfaces/CMakeLists.txt | 6 | ||||
-rw-r--r-- | xbmc/addons/interfaces/Network.cpp | 125 | ||||
-rw-r--r-- | xbmc/addons/interfaces/Network.h | 58 | ||||
-rw-r--r-- | xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h | 2 | ||||
-rw-r--r-- | xbmc/addons/kodi-addon-dev-kit/include/kodi/Network.h | 187 | ||||
-rw-r--r-- | xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h | 20 |
9 files changed, 405 insertions, 4 deletions
diff --git a/addons/kodi.binary.global.network/addon.xml.in b/addons/kodi.binary.global.network/addon.xml.in new file mode 100644 index 0000000000..dd56be41aa --- /dev/null +++ b/addons/kodi.binary.global.network/addon.xml.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<addon id="kodi.binary.global.network" version="@ADDON_GLOBAL_VERSION_NETWORK@" provider-name="Team Kodi"> + <backwards-compatibility abi="@ADDON_GLOBAL_VERSION_NETWORK_MIN@"/> + <requires> + <import addon="xbmc.core" version="0.1.0"/> + </requires> +</addon> diff --git a/system/addon-manifest.xml b/system/addon-manifest.xml index 0f034bd30d..727d1742fb 100644 --- a/system/addon-manifest.xml +++ b/system/addon-manifest.xml @@ -5,6 +5,7 @@ <addon>kodi.binary.global.audioengine</addon> <addon>kodi.binary.global.main</addon> <addon>kodi.binary.global.general</addon> + <addon>kodi.binary.global.network</addon> <addon>kodi.binary.global.gui</addon> <addon>kodi.binary.instance.adsp</addon> <addon>kodi.binary.instance.audiodecoder</addon> diff --git a/xbmc/addons/AddonDll.cpp b/xbmc/addons/AddonDll.cpp index 1fd7f189fa..f21ae294b3 100644 --- a/xbmc/addons/AddonDll.cpp +++ b/xbmc/addons/AddonDll.cpp @@ -39,6 +39,7 @@ // Global addon callback handle classes #include "addons/interfaces/AudioEngine.h" #include "addons/interfaces/General.h" +#include "addons/interfaces/Network.h" namespace ADDON { @@ -566,12 +567,14 @@ bool CAddonDll::InitInterface(KODI_HANDLE firstKodiInstance) Interface_General::Init(&m_interface); Interface_AudioEngine::Init(&m_interface); + Interface_Network::Init(&m_interface); return true; } void CAddonDll::DeInitInterface() { + Interface_Network::DeInit(&m_interface); Interface_AudioEngine::DeInit(&m_interface); Interface_General::DeInit(&m_interface); diff --git a/xbmc/addons/interfaces/CMakeLists.txt b/xbmc/addons/interfaces/CMakeLists.txt index 53d149975e..efc0075633 100644 --- a/xbmc/addons/interfaces/CMakeLists.txt +++ b/xbmc/addons/interfaces/CMakeLists.txt @@ -1,9 +1,11 @@ set(SOURCES AddonInterfaces.cpp AudioEngine.cpp - General.cpp) + General.cpp + Network.cpp) set(HEADERS AddonInterfaces.h AudioEngine.h - General.h) + General.h + Network.h) core_add_library(addonsBinaryInterfaces) diff --git a/xbmc/addons/interfaces/Network.cpp b/xbmc/addons/interfaces/Network.cpp new file mode 100644 index 0000000000..c34a8d9ac5 --- /dev/null +++ b/xbmc/addons/interfaces/Network.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "Network.h" + +#include "addons/kodi-addon-dev-kit/include/kodi/Network.h" + +#include "Application.h" +#include "PasswordManager.h" +#include "URL.h" +#include "addons/AddonDll.h" +#include "network/DNSNameCache.h" +#include "network/Network.h" +#include "utils/log.h" + +using namespace kodi; // addon-dev-kit namespace + +namespace ADDON +{ + +void Interface_Network::Init(AddonGlobalInterface *addonInterface) +{ + addonInterface->toKodi->kodi_network = static_cast<AddonToKodiFuncTable_kodi_network*>(malloc(sizeof(AddonToKodiFuncTable_kodi_network))); + + addonInterface->toKodi->kodi_network->wake_on_lan = wake_on_lan; + addonInterface->toKodi->kodi_network->get_ip_address = get_ip_address; + addonInterface->toKodi->kodi_network->dns_lookup = dns_lookup; + addonInterface->toKodi->kodi_network->url_encode = url_encode; +} + +void Interface_Network::DeInit(AddonGlobalInterface* addonInterface) +{ + if (addonInterface->toKodi && /* <-- needed as long as the old addon way is used */ + addonInterface->toKodi->kodi_network) + { + free(addonInterface->toKodi->kodi_network); + addonInterface->toKodi->kodi_network = nullptr; + } +} + +bool Interface_Network::wake_on_lan(void* kodiBase, const char* mac) +{ + CAddonDll* addon = static_cast<CAddonDll*>(kodiBase); + if (addon == nullptr || mac == nullptr) + { + CLog::Log(LOGERROR, "Interface_Network::%s - invalid data (addon='%p', mac='%p')", __FUNCTION__, addon, mac); + return false; + } + + return g_application.getNetwork().WakeOnLan(mac); +} + +char* Interface_Network::get_ip_address(void* kodiBase) +{ + CAddonDll* addon = static_cast<CAddonDll*>(kodiBase); + if (addon == nullptr) + { + CLog::Log(LOGERROR, "Interface_Network::%s - invalid data (addon='%p')", __FUNCTION__, addon); + return nullptr; + } + + std::string titleIP; + CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface(); + if (iface) + titleIP = iface->GetCurrentIPAddress(); + else + titleIP = "127.0.0.1"; + + char* buffer = nullptr; + if (!titleIP.empty()) + buffer = strdup(titleIP.c_str()); + return buffer; +} + +char* Interface_Network::dns_lookup(void* kodiBase, const char* url, bool* ret) +{ + CAddonDll* addon = static_cast<CAddonDll*>(kodiBase); + if (addon == nullptr || url == nullptr || ret == nullptr) + { + CLog::Log(LOGERROR, "Interface_Network::%s - invalid data (addon='%p', url='%p', ret='%p')", __FUNCTION__, addon, url, ret); + return nullptr; + } + + std::string string; + *ret = CDNSNameCache::Lookup(url, string); + char* buffer = nullptr; + if (!string.empty()) + buffer = strdup(string.c_str()); + return buffer; +} + +char* Interface_Network::url_encode(void* kodiBase, const char* url) +{ + CAddonDll* addon = static_cast<CAddonDll*>(kodiBase); + if (addon == nullptr || url == nullptr) + { + CLog::Log(LOGERROR, "Interface_Network::%s - invalid data (addon='%p', url='%p')", __FUNCTION__, addon, url); + return nullptr; + } + + std::string string = CURL::Encode(url); + char* buffer = nullptr; + if (!string.empty()) + buffer = strdup(string.c_str()); + return buffer; +} + +} /* namespace ADDON */ diff --git a/xbmc/addons/interfaces/Network.h b/xbmc/addons/interfaces/Network.h new file mode 100644 index 0000000000..286ed5142a --- /dev/null +++ b/xbmc/addons/interfaces/Network.h @@ -0,0 +1,58 @@ +#pragma once +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +struct AddonGlobalInterface; + +namespace ADDON +{ + + /*! + * @brief Global general Add-on to Kodi callback functions + * + * To hold network functions not related to a instance type and usable for + * every add-on type. + * + * Related add-on header is "./xbmc/addons/kodi-addon-dev-kit/include/kodi/Network.h" + */ + struct Interface_Network + { + static void Init(AddonGlobalInterface* addonInterface); + static void DeInit(AddonGlobalInterface* addonInterface); + + /*! + * @brief callback functions from add-on to kodi + * + * @note To add a new function use the "_" style to directly identify an + * add-on callback function. Everything with CamelCase is only to be used + * in Kodi. + * + * The parameter `kodiBase` is used to become the pointer for a `CAddonDll` + * class. + */ + //@{ + static bool wake_on_lan(void* kodiBase, const char* mac); + static char* get_ip_address(void* kodiBase); + static char* dns_lookup(void* kodiBase, const char* url, bool* ret); + static char* url_encode(void* kodiBase, const char* url); + //@} + }; + +} /* namespace ADDON */ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h index 3145049c07..6f2de58fab 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h @@ -145,6 +145,7 @@ typedef ADDON_HANDLE_STRUCT *ADDON_HANDLE; */ struct AddonToKodiFuncTable_kodi; struct AddonToKodiFuncTable_kodi_audioengine; +struct AddonToKodiFuncTable_kodi_network; typedef struct AddonToKodiFuncTable_Addon { // Pointer inside Kodi, used on callback functions to give related handle @@ -161,6 +162,7 @@ typedef struct AddonToKodiFuncTable_Addon AddonToKodiFuncTable_kodi* kodi; AddonToKodiFuncTable_kodi_audioengine* kodi_audioengine; + AddonToKodiFuncTable_kodi_network *kodi_network; } AddonToKodiFuncTable_Addon; /* diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/Network.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Network.h new file mode 100644 index 0000000000..f27b710cab --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Network.h @@ -0,0 +1,187 @@ +#pragma once +/* + * Copyright (C) 2005-2017 Team Kodi + * http://kodi.tv + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KODI; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "AddonBase.h" + +/* + * For interface between add-on and kodi. + * + * This structure defines the addresses of functions stored inside Kodi which + * are then available for the add-on to call + * + * All function pointers there are used by the C++ interface functions below. + * You find the set of them on xbmc/addons/interfaces/General.cpp + * + * Note: For add-on development itself this is not needed + */ +typedef struct AddonToKodiFuncTable_kodi_network +{ + bool (*wake_on_lan)(void* kodiBase, const char *mac); + char* (*get_ip_address)(void* kodiBase); + char* (*dns_lookup)(void* kodiBase, const char* url, bool* ret); + char* (*url_encode)(void* kodiBase, const char* url); +} AddonToKodiFuncTable_kodi_network; + +//============================================================================== +/// +/// \defgroup cpp_kodi_network Interface - kodi::network +/// \ingroup cpp +/// @brief **Network functions** +/// +/// The network module offers functions that allow you to control it. +/// +/// It has the header \ref Network.h "#include <kodi/Network.h>" be included +/// to enjoy it. +/// +//------------------------------------------------------------------------------ + +namespace kodi +{ +namespace network +{ + + //============================================================================ + /// + /// \ingroup cpp_kodi_network + /// @brief Send WakeOnLan magic packet. + /// + /// @param[in] mac Network address of the host to wake. + /// @return True if the magic packet was successfully sent, false otherwise. + /// + inline bool WakeOnLan(const std::string& mac) + { + return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->wake_on_lan(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, mac.c_str()); + } + //---------------------------------------------------------------------------- + + //============================================================================ + /// + /// \ingroup cpp_kodi_network + /// @brief To the current own ip address as a string. + /// + /// @return Own system ip. + /// + /// + /// ------------------------------------------------------------------------ + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include <kodi/Network.h> + /// ... + /// std::string ipAddress = kodi::network::GetIPAddress(); + /// fprintf(stderr, "My IP is '%s'\n", ipAddress.c_str()); + /// ... + /// ~~~~~~~~~~~~~ + /// + inline std::string GetIPAddress() + { + std::string ip; + char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->get_ip_address(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase); + if (string != nullptr) + { + ip = string; + ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); + } + return ip; + } + //---------------------------------------------------------------------------- + + //============================================================================ + /// + /// \ingroup cpp_kodi_network + /// @brief URL encodes the given string + /// + /// This function converts the given input string to a URL encoded string and + /// returns that as a new allocated string. All input characters that are + /// not a-z, A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" + /// version (%NN where NN is a two-digit hexadecimal number). + /// + /// @param[in] url The code of the message to get. + /// @return Encoded URL string + /// + /// + /// ------------------------------------------------------------------------ + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include <kodi/Network.h> + /// ... + /// std::string encodedUrl = kodi::network::URLEncode("François"); + /// fprintf(stderr, "Encoded URL is '%s'\n", encodedUrl.c_str()); + /// ... + /// ~~~~~~~~~~~~~ + /// For example, the string: François ,would be encoded as: Fran%C3%A7ois + /// + inline std::string URLEncode(const std::string& url) + { + std::string retString; + char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->url_encode(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, url.c_str()); + if (string != nullptr) + { + retString = string; + ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); + } + return retString; + } + //---------------------------------------------------------------------------- + + //============================================================================ + /// + /// \ingroup cpp_kodi_network + /// @brief Lookup URL in DNS cache + /// + /// This test will get DNS record for a domain. The DNS lookup is done directly + /// against the domain's authoritative name server, so changes to DNS Records + /// should show up instantly. By default, the DNS lookup tool will return an + /// IP address if you give it a name (e.g. www.example.com) + /// + /// @param[in] hostName The code of the message to get. + /// @param[out] ipAddress Returned address + /// @return true if successfull + /// + /// + /// ------------------------------------------------------------------------ + /// + /// **Example:** + /// ~~~~~~~~~~~~~{.cpp} + /// #include <kodi/Network.h> + /// ... + /// std::string ipAddress; + /// bool ret = kodi::network::DNSLookup("www.google.com", ipAddress); + /// fprintf(stderr, "DNSLookup returned for www.google.com the IP '%s', call was %s\n", ipAddress.c_str(), ret ? "ok" : "failed"); + /// ... + /// ~~~~~~~~~~~~~ + /// + inline bool DNSLookup(const std::string& hostName, std::string& ipAddress) + { + bool ret = false; + char* string = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_network->dns_lookup(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, hostName.c_str(), &ret); + if (string != nullptr) + { + ipAddress = string; + ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, string); + } + return ret; + } + //---------------------------------------------------------------------------- + +} /* namespace network */ +} /* namespace kodi */ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h index 80b673a576..2d197f2924 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h @@ -41,7 +41,7 @@ * overview. */ -#define ADDON_GLOBAL_VERSION_MAIN "1.0.5" +#define ADDON_GLOBAL_VERSION_MAIN "1.0.6" #define ADDON_GLOBAL_VERSION_MAIN_MIN "1.0.2" #define ADDON_GLOBAL_VERSION_MAIN_XML_ID "kodi.binary.global.main" #define ADDON_GLOBAL_VERSION_MAIN_DEPENDS "AddonBase.h" \ @@ -65,6 +65,11 @@ #define ADDON_GLOBAL_VERSION_AUDIOENGINE_XML_ID "kodi.binary.global.audioengine" #define ADDON_GLOBAL_VERSION_AUDIOENGINE_DEPENDS "AudioEngine.h" +#define ADDON_GLOBAL_VERSION_NETWORK "1.0.0" +#define ADDON_GLOBAL_VERSION_NETWORK_MIN "1.0.0" +#define ADDON_GLOBAL_VERSION_NETWORK_XML_ID "kodi.binary.global.network" +#define ADDON_GLOBAL_VERSION_NETWORK_DEPENDS "Network.h" + #define ADDON_INSTANCE_VERSION_ADSP "0.1.10" #define ADDON_INSTANCE_VERSION_ADSP_MIN "0.1.10" #define ADDON_INSTANCE_VERSION_ADSP_XML_ID "kodi.binary.instance.adsp" @@ -153,7 +158,8 @@ typedef enum ADDON_TYPE ADDON_GLOBAL_GUI = 1, ADDON_GLOBAL_AUDIOENGINE = 2, ADDON_GLOBAL_GENERAL = 3, - ADDON_GLOBAL_MAX = 3, // Last used global id, used in loops to check versions. Need to change if new global type becomes added. + ADDON_GLOBAL_NETWORK = 4, + ADDON_GLOBAL_MAX = 4, // Last used global id, used in loops to check versions. Need to change if new global type becomes added. /* addon type instances */ ADDON_INSTANCE_ADSP = 101, @@ -205,6 +211,10 @@ inline const char* GetTypeVersion(int type) case ADDON_GLOBAL_AUDIOENGINE: return ADDON_GLOBAL_VERSION_AUDIOENGINE; #endif +#if !defined(BUILD_KODI_ADDON) || defined(ADDON_GLOBAL_VERSION_NETWORK_USED) + case ADDON_GLOBAL_NETWORK: + return ADDON_GLOBAL_VERSION_NETWORK; +#endif /* addon type instances */ #if !defined(BUILD_KODI_ADDON) || defined(ADDON_INSTANCE_VERSION_ADSP_USED) @@ -276,6 +286,8 @@ inline const char* GetTypeMinVersion(int type) return ADDON_GLOBAL_VERSION_GENERAL_MIN; case ADDON_GLOBAL_AUDIOENGINE: return ADDON_GLOBAL_VERSION_AUDIOENGINE_MIN; + case ADDON_GLOBAL_NETWORK: + return ADDON_GLOBAL_VERSION_NETWORK_MIN; /* addon type instances */ case ADDON_INSTANCE_ADSP: @@ -324,6 +336,8 @@ inline const char* GetTypeName(int type) return "General"; case ADDON_GLOBAL_AUDIOENGINE: return "AudioEngine"; + case ADDON_GLOBAL_NETWORK: + return "Network"; /* addon type instances */ case ADDON_INSTANCE_ADSP: @@ -371,6 +385,8 @@ inline int GetTypeId(const char* name) return ADDON_GLOBAL_GUI; else if (strcmp(name, "audioengine") == 0) return ADDON_GLOBAL_AUDIOENGINE; + else if (strcmp(name, "network") == 0) + return ADDON_GLOBAL_NETWORK; else if (strcmp(name, "adsp") == 0) return ADDON_INSTANCE_ADSP; else if (strcmp(name, "audiodecoder") == 0) |