
{"id":2603,"date":"2023-06-27T06:38:16","date_gmt":"2023-06-27T06:38:16","guid":{"rendered":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk_video-guide\/"},"modified":"2025-03-25T05:18:37","modified_gmt":"2025-03-25T05:18:37","slug":"rdk-video-guide","status":"publish","type":"page","link":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/","title":{"rendered":"RDK Video Guide"},"content":{"rendered":"<div class=\"contentLayout2\">\n<div class=\"columnLayout two-right-sidebar\" data-layout=\"two-right-sidebar\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<p><span>This document guides users to perform the below activities on a Raspberry Pi (Rpi) platform<\/span><\/p>\n<ul>\n<li>Setup a development environment for an IPSTB target<\/li>\n<li>Bring up the device<\/li>\n<li>Create &amp; run a sample lightning app on the device<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<div class=\"cell aside\" data-type=\"aside\">\n<div class=\"innerCell\">\n<div class=\"confluence-information-macro has-no-icon confluence-information-macro-information conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"info\">\n<div class=\"confluence-information-macro-body\">\n<div class=\"toc-macro client-side-toc-macro  conf-macro output-block\" data-headerelements=\"H1,H2\" data-hasbody=\"false\" data-macro-name=\"toc\"> <\/div>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Before you begin<\/span><\/h3>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<hr>\n\t\t\t<\/div>\n<\/p>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<h3 id=\"RDKVideoGuide-BasicSkills\"><span>Basic Skills<\/span><\/h3>\n<p><span>Though not mandatory, the below skills will help the user to understand RDK, RDK build, and to try out RDK better :<\/span><\/p>\n<ul>\n<li>Familiar with Linux based platforms<\/li>\n<li>Familiar with Yocto<\/li>\n<li>Familiar with RDK basics<\/li>\n<li>Knowledge in using Raspberry Pi<\/li>\n<li><span>Experience in setting up boards<\/span><\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<h3 id=\"RDKVideoGuide-RelevantRDKlinks\">Relevant RDK links<\/h3>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout three-equal\" data-layout=\"three-equal\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-RDKSupport\"><strong>RDK Support<\/strong><\/h4>\n<ul>\n<li>Forum: <a href=\"https:\/\/wiki.rdkcentral.com\/display\/FORUMS\/FORUMS+Home\">FORUMS Home<\/a><\/li>\n<li><span>JIRA: <\/span><a href=\"https:\/\/jira.rdkcentral.com\" class=\"external-link\" rel=\"nofollow\">https:\/\/jira.rdkcentral.com<\/a><\/li>\n<li><span>Support: <\/span><a href=\"mailto:support@rdkcentral.com\" class=\"external-link\" rel=\"nofollow\">RDK Support<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-RDKSourceCode\"><strong>RDK Source Code<\/strong><\/h4>\n<ul>\n<li>Gerrit: <a href=\"https:\/\/code.rdkcentral.com\" class=\"external-link\" rel=\"nofollow\">https:\/\/code.rdkcentral.com<\/a><\/li>\n<li><span>Component Owners: <\/span><a href=\"https:\/\/wiki.rdkcentral.com\/display\/RDK\/RDK+Component+owners\" rel=\"nofollow\">RDK Component owners<\/a><\/li>\n<li><span>Code Contribution Process: <a href=\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/how_to_contribute\/\" class=\"external-link\" rel=\"nofollow\">How to Contribute<\/a><\/span><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-DoxygenDocumentation\"><strong>Doxygen Documentation<\/strong><\/h4>\n<ul>\n<li>RDK-V Opensourced Doxygen Documentation : <a href=\"https:\/\/wiki.rdkcentral.com\/doxygen\/rdkv-opensourced\/\" rel=\"nofollow\">Opensourced API Documentation<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout three-equal\" data-layout=\"three-equal\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-ThunderJSDocumentation\"><span><strong>ThunderJS Documentation<\/strong><\/span><\/h4>\n<ul>\n<li>An elaborate ThunderJS documentation is available <a href=\"https:\/\/github.com\/rdkcentral\/ThunderJS\" class=\"external-link\" rel=\"nofollow\">here<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-FAQ\"><strong>FAQ<\/strong><\/h4>\n<ul>\n<li>Refer the link for FAQ: <a href=\"https:\/\/developer.rdkcentral.com\/support\/support\/rdk_faq\/\" class=\"external-link\" rel=\"nofollow\">RDK FAQ<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\"oc-documentation-card conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"div\">\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<h4 id=\"RDKVideoGuide-RDKReleases\"><strong>RDK Releases<\/strong><\/h4>\n<ul>\n<li><a href=\"https:\/\/wiki.rdkcentral.com\/display\/CMF\/RDK-V+Releases\">RDK-V Releases<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"columnMacro conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"column\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<h3 id=\"RDKVideoGuide-Prerequisites\">Prerequisites<\/h3>\n<\/p>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Requirement<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\"><strong>Yocto 3.1 LTS (Dunfell)<\/strong><\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Linux PC<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>64 bit Ubuntu 18.04 LTS<\/p>\n\t\t\t\t\t\t\t\t\t<p>Precise supported distributions and versions are&nbsp;<a href=\"https:\/\/www.yoctoproject.org\/docs\/3.1\/ref-manual\/ref-manual.html#detailed-supported-distros\" class=\"rdk-inside-table\" rel=\"nofollow\">here<\/a><\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Free HDD Space<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Minimum 100GB Free memory space<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Host Tools version<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Git 1.8.3.1 or greater<\/p>\n\t\t\t\t\t\t\t\t\t<p>tar 1.24 or greater<\/p>\n\t\t\t\t\t\t\t\t\t<p>Python 2.7.3<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">Raspberry Pi development kit<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">IPSTB Reference board<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Access to repositories hosting code and binaries for reference board<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Peripherals<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">TV, Keyboard<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Environment<\/span><\/h3>\n<\/p>\n<\/div>\n<hr>\n<p><strong>Rpi &amp; IPSTB similarities:<\/strong><\/p>\n<ul>\n<li><span>Reference devices to try and run RDK<\/span><\/li>\n<li>No need of RDK license to try out IPSTB builds<\/li>\n<\/ul>\n<p><strong>Difference between <span>Raspberry Pi (<\/span>Rpi) and IPSTB:<\/strong><\/p>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">\n\t\t\t\t\t\t\t\t\t<p><strong><span>Raspberry Pi (<\/span>Rpi)<\/strong><\/p>\n\t\t\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">\n\t\t\t\t\t\t\t\t\t<p><strong>IPSTB<\/strong><\/p>\n\t\t\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Generic hobby device altered in software for STB capabilities<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Hardware specifically made for STB purpose<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Low end device capable of only mimicking STB capabilities<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Regular hardware used in real STBs<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Available in general market<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Available for licensed users of SoC vendor<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>No licenses required to generate and use builds<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Agreement with IPSTB SoC vendor required to obtain software licenses (such as SDK, Kernel etc.)<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>Rpi builds supported in all quarterly releases<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">\n\t\t\t\t\t\t\t\t\t<p>IPSTB builds might not be regularly supported in all quarterly releases<\/p>\n\t\t\t\t\t\t\t\t<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<h3 id=\"RDKVideoGuide-HostSetup\"><span>Host Setup<\/span><\/h3>\n<h4 id=\"RDKVideoGuide-InstallthefollowingpackagesforsettingupyourhostVM\">Install the following packages for setting up your host VM<\/h4>\n<p><span>The instructions provided below are meant to be executed via the command line on an Ubuntu machine<\/span><\/p>\n<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>for yocto 3.1 (dunfell)<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># essential packages installation\n# super user mode is required\n\n# major essential packages\nsudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib g++-multilib build-essential chrpath socat bison curl cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-Configurebashasdefaultcommandinterpreterforshellscripts\"><span>Configure bash as default command interpreter for shell scripts<\/span><\/h4>\n<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">sudo dpkg-reconfigure dash<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span>Select &ldquo;No&rdquo;<\/span><br \/><span>To choose bash, when the prompt asks if you want to use dash as the default system shell &#8211; select &ldquo;No&rdquo;<\/span><\/p>\n<h4 id=\"RDKVideoGuide-ConfigureGit\"><span>Configure Git<\/span><\/h4>\n<p><span>Upgrade your Git version to 1.8.x or higher<\/span><\/p>\n<p class=\"auto-cursor-target\"><span>Once git is installed, configure your name and email using the below commands<\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># review your existing configuration\ngit config --list --show-origin\n\n# configure user name and email address\ngit config --global user.name \"John Doe\"\ngit config --global user.email johndoe@example.com\n\n# configure git cookies. Needed for Gerrit to only contact the LDAP backend once.\ngit config --global http.cookieFile \/tmp\/gitcookie.txt\ngit config --global http.saveCookies true<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-Configurerepo\"><span>Configure repo<\/span><\/h4>\n<p><span>In order to use Yocto build system, first you need to make sure that repo is properly installed on the machine:<\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># create a bin directory\nmkdir ~\/bin\nexport PATH=~\/bin:$PATH\n\n# Download the repo tool and ensure that it is executable\ncurl&nbsp;http:\/\/commondatastorage.googleapis.com\/git-repo-downloads\/repo&nbsp;&gt; ~\/bin\/repo\nchmod a+x ~\/bin\/repo<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>Note<\/strong><span>: it is also recommended to put credentials in .netrc when interacting with the repo.<\/span><\/p>\n<p>A sample .netrc file is illustrated below<\/p>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">\n\t\t\t\t\t\t\t\t\t<p>machine<span>&nbsp;<\/span><a href=\"http:\/\/code.rdkcentral.com\/\" class=\"rdk-inside-table\" rel=\"nofollow\">code.rdkcentral.com<\/a><\/p>\n\t\t\t\t\t\t\t\t\t<p>&nbsp; &nbsp; login &lt;YOUR_USERNAME&gt;<\/p>\n\t\t\t\t\t\t\t\t\t<p>&nbsp; &nbsp; password &lt;YOUR_PASSWORD&gt;<\/p>\n\t\t\t\t\t\t\t\t<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Build<\/span><\/h3>\n<\/p>\n<\/div>\n<hr>\n<h3 id=\"RDKVideoGuide-BuildbasicimageforRpi:\">Build basic image for Rpi:<\/h3>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># initialize the manifest with repo tool\nrepo init -u https:\/\/code.rdkcentral.com\/r\/manifests -b dunfell -m rdkv-nosrc.xml\nrepo sync -j `nproc` --no-clone-bundle --no-tags\nMACHINE=raspberrypi-rdk-mc source meta-cmf-raspberrypi\/setup-environment\nbitbake rdk-generic-mediaclient-wpe-image<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span>The generated image resides under the directory <\/span><code>build-&lt;MACHINE&gt;\/tmp\/deploy\/images\/&lt;MACHINE&gt;<\/code><span>&nbsp;of the Yocto workspace<\/span><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Flash image and bring up<\/span><\/h3>\n<\/p>\n<\/div>\n<h3 id=\"RDKVideoGuide-FlashimageandbringupRpi:\"><u>Flash image and bring up Rpi :<\/u><\/h3>\n<h4 id=\"RDKVideoGuide-Flashimage\">Flash image<\/h4>\n<p>1. Insert an SD card in the SD card port of the USB SD card reader (or Laptop).<\/p>\n<p>&nbsp; &nbsp; &nbsp;<strong>Prefer to use 32gb sd card and there should be minimum 12gb free space available in the device .<\/strong><\/p>\n<p>2. Verify that the SD card has been detected by executing either of the commands listed below<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$lsblk\n$sudo fdisk &ndash;l <\/pre>\n<\/p>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ lsblk\nNAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT\nsda      8:0    0 931.5G  0 disk\n&#9500;&#9472;sda1   8:1    0   350M  0 part\n&#9500;&#9472;sda2   8:2    0     3G  0 part\n&#9500;&#9472;sda3   8:3    0 896.4G  0 part \/\n&#9500;&#9472;sda4   8:4    0     1K  0 part\n&#9492;&#9472;sda5   8:5    0  31.8G  0 part [SWAP]\nsdb      8:16   1  14.9G  0 disk\n&#9500;&#9472;sdb1   8:17   1    40M  0 part \/media\/raspberrypi\n&#9492;&#9472;sdb2   8:18   1   552M  0 part \/media\/dd5efb34-1d40-4e50-bbc2-a75d3e02af97\nsr0     11:0    1  1024M  0 rom<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span>3. Type the following command to ensure that the partitions, if present, on the SD card are not mounted<\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$mount<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ mount\n\/dev\/sda3 on \/ type ext4 (rw,errors=remount-ro)\nproc on \/proc type proc (rw,noexec,nosuid,nodev)\nsysfs on \/sys type sysfs (rw,noexec,nosuid,nodev)\nnone on \/sys\/fs\/fuse\/connections type fusectl (rw)\nnone on \/sys\/kernel\/debug type debugfs (rw)\nnone on \/sys\/kernel\/security type securityfs (rw)\nudev on \/dev type devtmpfs (rw,mode=0755)\ndevpts on \/dev\/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)\ntmpfs on \/run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)\nnone on \/run\/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)\nnone on \/run\/shm type tmpfs (rw,nosuid,nodev)\nbinfmt_misc on \/proc\/sys\/fs\/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)\nrpc_pipefs on \/run\/rpc_pipefs type rpc_pipefs (rw)\nnfsd on \/proc\/fs\/nfsd type nfsd (rw)\nnone on \/tmp\/guest-zdrO76 type tmpfs (rw,mode=700)\ngvfs-fuse-daemon on \/var\/lib\/lightdm\/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=lightdm)\n\/dev\/sdb1 on \/media\/raspberrypi type vfat (rw,nosuid,nodev,uid=136,gid=148,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks)\n\/dev\/sdb2 on \/media\/dd5efb34-1d40-4e50-bbc2-a75d3e02af97 type ext3 (rw,nosuid,nodev,uhelper=udisks)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>4. Repeat the below command to unmount all the mounted partition present on the SD card.<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$umount &lt;partition-mountpoint&gt;<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$ sudo umount \/dev\/sdb1\n$ lsblk\nNAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT\nsda      8:0    0 931.5G  0 disk\n&#9500;&#9472;sda1   8:1    0   350M  0 part\n&#9500;&#9472;sda2   8:2    0     3G  0 part\n&#9500;&#9472;sda3   8:3    0 896.4G  0 part \/\n&#9500;&#9472;sda4   8:4    0     1K  0 part\n&#9492;&#9472;sda5   8:5    0  31.8G  0 part [SWAP]\nsdb      8:16   1  14.9G  0 disk\n&#9500;&#9472;sdb1   8:17   1    40M  0 part\n&#9492;&#9472;sdb2   8:18   1   552M  0 part \/media\/dd5efb34-1d40-4e50-bbc2-a75d3e02af97\nsr0     11:0    1  1024M  0 rom\n$ sudo umount \/dev\/sdb2\n$ lsblk\nNAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT\nsda      8:0    0 931.5G  0 disk\n&#9500;&#9472;sda1   8:1    0   350M  0 part\n&#9500;&#9472;sda2   8:2    0     3G  0 part\n&#9500;&#9472;sda3   8:3    0 896.4G  0 part \/\n&#9500;&#9472;sda4   8:4    0     1K  0 part\n&#9492;&#9472;sda5   8:5    0  31.8G  0 part [SWAP]\nsdb      8:16   1  14.9G  0 disk\n&#9500;&#9472;sdb1   8:17   1    40M  0 part\n&#9492;&#9472;sdb2   8:18   1   552M  0 part\nsr0     11:0    1  1024M  0 rom<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>5. Execute the following command to flash the image on the SD card<\/p>\n<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>Flash Command<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">$sudo dd if=&lt;path to ImageName.Rpi-sdimg&gt; of=&lt;path to SD card space&gt; bs=4M\nExample:\n$sudo dd if=rdk-generic-mediaclient-wpe-image.Rpi-sdimg of=\/dev\/sdb bs=4M\n149+0 records in\n149+0 records out\n624951296 bytes (625 MB) copied, 39.7752 s, 15.7 MB\/s<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span>6. Remove the SD card and insert it to the Raspberry Pi SD card slot&nbsp;<\/span><\/p>\n<p><span>7. Power on the Rpi and Bring up the device<\/span><\/p>\n<ul>\n<li><span>TV screen will display the Raspberry Pi&#8217;s IP address(referred as machineIP from now) with default RDK UI as shown below.<\/span><\/li>\n<\/ul>\n<p><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/Device%20bringup.png\"><\/span><\/p>\n<\/p>\n<h4 class=\"auto-cursor-target\" id=\"RDKVideoGuide-AccessingRaspberryPi\">Accessing Raspberry Pi<\/h4>\n<ul>\n<li>&nbsp;For connecting Controller UI, use URL: http:\/\/&lt;machineIP&gt;:9998<\/li>\n<\/ul>\n<p><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/controllerui.png\"><\/span><\/p>\n<ul>\n<li>Plugins can be enabled or disabled from controller UI.&nbsp;<\/li>\n<\/ul>\n<p><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/apps_window.png\"><\/span><\/p>\n<ul>\n<li>Wifi related services can be triggered from Wi-Fi tab in controller UI. We can scan and select from available networks.<\/li>\n<\/ul>\n<p><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/wifi.png\"><\/span><\/p>\n<ul>\n<li>For ssh, we can use ssh root@machineip<\/li>\n<li>For verifying the image details, we can use cat \/version.txt command.&nbsp;<\/li>\n<\/ul>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">root@raspberrypi-rdk-ipmc:~# cat \/version.txt&nbsp;\n\nimagename:rdk-generic-ip-stb-client_rdk-next_20210902101930\n\nBRANCH=rdk-next\n\nYOCTO_VERSION=dunfell\n\nVERSION=4.09.02.21\n\nSPIN=0\n\nBUILD_TIME=\"2021-09-02 10:19:30\"\n\nGenerated on Thu Sep 02 &nbsp;10:19:30 UTC 2021\n\nroot@raspberrypi-rdk-ipmc:~#&nbsp;<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<ul>\n<li>For playing a video using aamp-cli, launch aamp-cli from terminal, cd \/usr\/bin;aamp-cli.<\/li>\n<\/ul>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">root@raspberrypi-rdk-mc:\/usr\/bin# aamp-cli\n**************************************************************************\n** ADVANCED ADAPTIVE MICRO PLAYER (AAMP) - COMMAND LINE INTERFACE (CLI) **\n**************************************************************************\n1644303267:124 : [AAMP-PLAYER][-1][WARN][PlayerInstanceAAMP][144][AAMP_JS][0x104ae00]Creating GlobalConfig Instance[0x104ff30]\n1644303267:124 : [AAMP-PLAYER]ReadAampCfgTxtFile:INFO opened aamp.cfg\n\n1644303267:124 : [AAMP-PLAYER]Parsed value for dev cfg property useWesterosSink - 1\n1644303267:124 : [AAMP-PLAYER]SetValue: useWesterosSink New Owner[5]\n1644303267:124 : [AAMP-PLAYER]AAMP_ENABLE_WESTEROS_SINK present, Value = 1\n1644303267:124 : [AAMP-PLAYER]AAMP_ENABLE_WESTEROS_SINK present: Enabling westeros-sink.\n1644303267:124 : [AAMP-PLAYER]SetValue: useWesterosSink Owner[1] not allowed to Set ,current Owner[5]\n1644303267:124 : [AAMP-PLAYER]\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ AAMP Cfg Override Configuration  \/\/\/\/\/\/\/\/\/\/\n1644303267:124 : [AAMP-PLAYER]Cfg [53 ][useWesterosSink     ][cfg  ][true]\n1644303267:124 : [AAMP-PLAYER]\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n1644303267:124 : [AAMP-PLAYER]\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ AAMP Config (Operator Set) \/\/\/\/\/\/\/\/\/\/\n1644303267:124 : [AAMP-PLAYER]\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n1644303267:125 : [AAMP-PLAYER]SetValue: userAgent New Owner[3]\n1644303267:125 : [AAMP-PLAYER][0][WARN][CreatePipeline][1580]Creating gstreamer pipeline\n1644303267:125 : [AAMP-PLAYER][0][WARN][CreatePipeline][1607]AAMPGstPlayerPipeline buffering_enabled 1\n[AAMPCLI] type 'help' for list of available commands\n[AAMPCLI] aamp-cli&gt;<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<ul>\n<li>For playing a video using gstreamer, use gst-launch-1.0.<\/li>\n<li>eg :- gst-launch-1.0 playbin uri=<a href=\"\/\/bitdash-a.akamaihd.net\/content\/MI201109210084_1\/m3u8s\/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8\" rel=\"nofollow\">aamp:\/\/bitdash-a.akamaihd.net\/content\/MI201109210084_1\/m3u8s\/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8<\/a><span>&nbsp;<\/span>video-sink=westerossink<\/li>\n<\/ul>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">root@raspberrypi-rdk-mc:~# gst-launch-1.0 playbin uri=aamp:\/\/bitdash-a.akamaihd.net\/content\/MI201109210084_1\/m3u8s\/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8 video-sink=westerossink\nSetting pipeline to PAUSED ...\nwesteros (sink) version 1.01.28\nPipeline is PREROLLING ...\n\n^Chandling interrupt.\nInterrupt: Stopping pipeline ...\nERROR: pipeline doesn't want to preroll.\nSetting pipeline to NULL ...\nFreeing pipeline ...\nNumber of active jsmediaplayer instances: 0\nroot@raspberrypi-rdk-mc:~#<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Yocto recipe structure<\/span><\/h3>\n<\/p>\n<\/div>\n<p>Below is the major meta-layers specific to Raspberry Pi.<\/p>\n<h3 id=\"RDKVideoGuide-RaspberryPimajormeta-layersstructure:\">Raspberry Pi major meta-layers structure:<\/h3>\n<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/Raspberrypi%20recipe%20structure.png\"><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Setup and Develop Thunder plugin<\/span><\/h3>\n<\/p>\n<\/div>\n<hr>\n<p><span>Steps involved in implementing new RDK services Plug-In<\/span><\/p>\n<p><span>RDK components implemented as Thunder plugins are called as RDKServices.<\/span><span> it is&nbsp; developed based on the Thunder (WPE) Framework. Services each other or a particular service can be COMRPC for (communication between plugins) or JSONRPC (for external communication). It has a web-based controller UI.<\/span><\/p>\n<p><span>Reference : <a href=\"https:\/\/github.com\/rdkcentral\/rdkservices\/pull\/960\" title=\"https:\/\/github.com\/rdkcentral\/rdkservices\/pull\/960\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/rdkservices\/pull\/960<\/a>&nbsp;<\/span><\/p>\n<p>&nbsp;In RDK services -plugins workspace:<\/p>\n<p>&nbsp;Cloned from <a href=\"https:\/\/github.com\/rdkcentral\/rdkservices\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/rdkservices<\/a><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"><code class=\"language-console\">\t$ git clone https:\/\/github.com\/rdkcentral\/rdkservices<\/code><span><code>\n<\/code><\/span><\/pre>\n<h3 id=\"RDKVideoGuide-InsidePluginNamedirectory\">Inside PluginName directory<\/h3>\n<ol>\n<li>\n\t\t\t\t\t\t&nbsp;&lt;PluginName&gt;.json : This file contains the plugin&#8217;s information like schema, information and interface json file.<\/p>\n<ol>\n<li>PluginTemplate.json<\/li>\n<\/ol>\n<\/li>\n<li>&nbsp;CmakeLists.txt:&nbsp; <a href=\"https:\/\/cmake.org\/overview\/\" class=\"external-link\" rel=\"nofollow\"> CMAKE <\/a>based configuration file which <span>contains a set of directives and instructions describing the project&#8217;s source files and targets. This is used to<\/span> compile the Plug-in code to generate the plugin library(Shared library by default; &ldquo;.so&rdquo;). External dependencies can be included\/linked to the target with the help of CMakeLists.txt configurations.<\/li>\n<li>Module.h: This header file includes the support for JSON request, response, logging etc&#8230;<\/li>\n<li>Module.cpp: This file is used to declare the module name for the Plug-in. This file contains the plugin&#8217;s information like schema, information and interface json file (defined earlier).<\/li>\n<li>&lt;PluginName&gt;.config: This file is used to set configurations of the Plug-in . Ex:- set (autostart true) &#8211; Used to make the Plug-in to start automatically along with wpeframework daemon<\/li>\n<li>&lt;PluginName&gt;.h :Declare the plugin class in this which should contains all the structures, variables and methods which are needed for plugin implementation. The interface header auto-generated earlier will be used here,<\/li>\n<li>&lt;PluginName&gt;.cpp: This class does contains all the definitions for the methods declared in the Plugin.h and those definitions should be defined inside the below namespace.<\/li>\n<li>Cmake \/ (directory) :<br \/>&nbsp;&nbsp;<\/li>\n<\/ol>\n<p>PluginTemplate\/<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; CMakeLists.txt<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; PluginTemplate.config<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; PluginTemplate.cpp<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; PluginTemplate.h<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; PluginTemplate.json<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; Module.cpp<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; Module.h<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; <a href=\"http:\/\/README.md\" class=\"external-link\" rel=\"nofollow\">README.md<\/a><br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; cmake<br \/>&nbsp;&nbsp;|&nbsp;&nbsp; &#9500;&#9472;&#9472; FindDS.cmake<br \/>&nbsp;&nbsp;&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; FindIARMBus.cmake<br \/>&nbsp;&nbsp;&#9492;&#9472;&#9472; doc<br \/>&nbsp;&nbsp;&nbsp;&#9492;&#9472;&#9472; PluginTemplate.md<\/p>\n<h4 id=\"RDKVideoGuide-&lt;PluginName&gt;.json\">&lt;PluginName&gt;.json<\/h4>\n<p>&nbsp;This file contains the plugin&#8217;s information like schema, information and interface json file.<\/p>\n<p>Syntax :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">   {\n    {\n&nbsp;&nbsp;&nbsp;&nbsp;\"$schema\": \"plugin.schema.json\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"info\": {\n&nbsp;&nbsp;&nbsp;&nbsp;\"title\": \"Plugin Name Plugin\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"callsign\": \"PluginName\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"locator\": \"libWPEFrameworkPluginName.so\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"status\": \"production\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"description\": \"The PluginName plugin allows retrieving of various plugin-related information.\",\n&nbsp;&nbsp;&nbsp;&nbsp;\"version\": \"1.0\"\n&nbsp;&nbsp;&nbsp;&nbsp; },\n&nbsp;&nbsp;&nbsp;&nbsp; \"interface\": {\n&nbsp;&nbsp;&nbsp;&nbsp;\"$ref\": \"{interfacedir}\/PluginName.json#\"\n&nbsp;&nbsp;&nbsp;&nbsp; }\n&nbsp;&nbsp;&nbsp;}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>eg: PluginTemplate.json<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"> {\n&nbsp;&nbsp;&nbsp;&nbsp; \"locator\":\"libWPEFrameworkPluginTemplate.so\",\n&nbsp;&nbsp;&nbsp;&nbsp; \"classname\":\"PluginTemplate\",\n&nbsp;&nbsp;&nbsp;&nbsp; \"precondition\":[\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \"Platform\"\n&nbsp;&nbsp;&nbsp;&nbsp; ],\n&nbsp;&nbsp;&nbsp;&nbsp; \"callsign\":\"org.rdk.PluginTemplate\",\n&nbsp;&nbsp;&nbsp;&nbsp; \"autostart\":false\n } <\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-&lt;PluginName&gt;.config\"><code><br \/>\n\t\t\t\t\t<\/code>&lt;PluginName&gt;.config<br \/>\n\t\t\t\t<\/h4>\n<p>.config files are files used to configure the parameters and initial settings for some computer programs.<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">set (autostart false) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #we are setting autostart condition disable \nset (preconditions Platform) \nset (callsign \"org.rdk.PluginTemplate\") \t#The callsign name was given to an instance of a plugin. \n\n#One plugin can be instantiated multiple times. but each instance, the instance-name \"callsign\" must be unique. here we using org.rdk.PluginTemplate. <\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-&lt;PluginName&gt;.h\">&lt;PluginName&gt;.h<\/h4>\n<p>Declare the plugin class in this which should contain all the structures, variables, and methods which are needed for plugin implementation.&nbsp;<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;namespace WPEFramework {\n&nbsp;&nbsp;namespace Plugin {\n&nbsp;&nbsp; \n&nbsp;&nbsp;&nbsp;class PluginName : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC {\n&nbsp;&nbsp;&nbsp;public:\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginName()\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: _skipURL(0)\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, _service(nullptr)\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, _subSystem(nullptr)\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RegisterAll();\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual ~PluginName()\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UnregisterAll();\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;}\n &nbsp; ---------------------------------------\n &nbsp; ---------------------------------------\n  }\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>eg: PluginTemplate.h<\/p>\n<p>for more information refer PluginTemplate.h&nbsp;<\/p>\n<h4 id=\"RDKVideoGuide-&lt;PluginName&gt;.cpp\">&lt;PluginName&gt;.cpp<\/h4>\n<p>This class does contain all the definitions for the methods declared in the PluginTemplate.h and those definitions should be defined inside the below namespace.&nbsp;<\/p>\n<p>The plugin should register using service registration MACRO as declared below :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;&nbsp;namespace WPEFramework {\n&nbsp;&nbsp;&nbsp;namespace Plugin {&nbsp; \n&nbsp;&nbsp;&nbsp;&nbsp;SERVICE_REGISTRATION(Plugin, 1, 0);\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>&nbsp;To initialize and deinitialize or activate or deactivate handler for the plugin services :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">const string PluginTemplate::Initialize(PluginHost::IShell* \/* service *\/)\n\t{\n\t\/\/shared pointer initialized\n\t\/\/initialize external library\n&nbsp; &nbsp; &nbsp; &nbsp; LOGINFO();\n&nbsp; &nbsp; &nbsp; &nbsp; return (string());\n&nbsp; &nbsp; &nbsp; &nbsp; }\nvoid PluginTemplate::Deinitialize(PluginHost::IShell* \/* service *\/)\n&nbsp; &nbsp; &nbsp; &nbsp; {\n \t\/\/shared pointer deinitialized\n\t\/\/deinitialize external library\n&nbsp; &nbsp; &nbsp; &nbsp; LOGINFO();\n&nbsp; &nbsp; &nbsp; &nbsp; }<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>eg:<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">namespace WPEFramework {\n&nbsp; &nbsp; namespace Plugin { &nbsp;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SERVICE_REGISTRATION(Plugin, 1, 0);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/registration\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/All the methods declared in Plugin.h should be registered here\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/initialize and deinitialize the handlers for the plug-in service\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/All the methods declared in Plugin.h should be defined here\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\n&nbsp; &nbsp; }\n}&nbsp;<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-CMakeLists.txt\">CMakeLists.txt<\/h4>\n<p>Using the CMake utility this file contains the task needed to be done to make a plug-in. Also contains packages, libraries needed to compile, its path, and other plugin-in configuration option.<\/p>\n<p>This file contains a set of directives and instructions describing the project&#8217;s source files and targets (executable, library, or both).<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">set(PLUGIN_NAME PluginTemplate)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# to set a environment variable set(&lt;variable&gt; &lt;value&gt;)\nset(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME})\nfind_package(${NAMESPACE}Plugins REQUIRED)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# to Finds and loads settings from an external project.\n\n#Adds a library target called &lt;name&gt; to be built from the source files listed in the command invocation. The &lt;name&gt; corresponds to the logical target name and must be globally unique within a project.\nadd_library(${MODULE_NAME} SHARED\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PluginTemplate.cpp\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Module.cpp\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ..\/helpers\/utils.cpp)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h3 id=\"RDKVideoGuide-Codeflow\">Code flow<\/h3>\n<ul>\n<li>Enable or disable the plug-in flag in the recipe file.<\/li>\n<li>Add this flag into the main CMakeLists.txt file present in the rdkservice.<\/li>\n<li>It will invoke CMakeLists file present in the &lt;plugin name&gt;\/ (eg: PluginTemplate\/CMakeLists.txt).<\/li>\n<li>When this file started to execute it finds dependencies, packages. it compiled and generate .so file.<\/li>\n<\/ul>\n<h3 id=\"RDKVideoGuide-ToaddplugininrdkservicesCMakeLists.txt\"><span>To add plugin in rdkservices CMakeLists.txt<\/span><\/h3>\n<p>In rdkservices directory open CmakeLists.txt :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"><code>\t$ vi CmakeLists.txt\n<\/code><\/pre>\n<p>add these lines ( by default its disabled ) :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;&nbsp;&nbsp; if(PLUGIN_PLUGINTEMPLATE)\n&nbsp;&nbsp;&nbsp;&nbsp;\tadd_subdirectory(PluginTemplate)\n&nbsp;&nbsp;&nbsp; endif()<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>&nbsp;it will invoke your CMakeLists.txt file present in your plugin directory.<\/p>\n<h3 id=\"RDKVideoGuide-CompilationandInstall\">Compilation and Install<\/h3>\n<p>To include <em><strong>plugintemplate<\/strong><\/em> plugin in build sequence, Open rdkservices recipe file and add below line. By default; its configured to be disabled while building <code>rdkservices.<\/code><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"><code>            $ vi meta-rdk-video\/recipes-extended\/rdkservices\/rdkservices_git.bb\n<\/code><\/pre>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">PACKAGECONFIG[plugintemplate]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = \" -DPLUGIN_PLUGINTEMPLATE=OFF,-DPLUGIN_PLUGINTEMPLATE=ON, \"  <\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>To include the plugin in rdkservises build; add the same in packageconfig in rdkservices recipe:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">              PACKAGECONFIG += \" plugintemplate\"<\/pre>\n<p>to compile and install in build directory :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"><code>\t$ bitbake -c compile -f rdkservices\n<\/code><\/pre>\n<p>once build complete copy .json, .so file into raspberry Pi.<\/p>\n<p>Copy the Plugin.json (eg: PluginTemplate.json) file to &ldquo;\/etc\/WPEFramework\/plugins&rdquo; in raspberry Pi<\/p>\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Copy the plugin library (libWPEFrameworkPluginTemplate.so) to &ldquo;\/usr\/lib\/wpeframework\/plugins&rdquo;<\/p>\n<p>so that the controller plugin identify it and list it in the WebUI ( controller UI ).<\/p>\n<h3 id=\"RDKVideoGuide-ControllerUI\">Controller UI<\/h3>\n<p>Controller UI is a web UI that can be launched from a host machine&#8217;s (machine under the same network where Rpi resides) browser. This UI can be loaded with the Rpi box&#8217;s IP address with Thunder&#8217;s port number configured. RDKServices uses 9998 as port.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"><code><br>\t\tURL: http:\/\/&lt;IP address of the Target device&gt;:9998\n<\/code><\/pre>\n<\/p>\n<p>Defalut page of Controller UI shall be loaded on web-browser and that will be of Controller tab. Controller tab allows all available plugins to be enabled or disabled.<\/p>\n<\/p>\n<p><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/controller%20UI.PNG\"><\/span><\/p>\n<h3 id=\"RDKVideoGuide-PluginTemplateJSONRPCcommand\">PluginTemplate JSON RPC command<\/h3>\n<p>Each RDK Service can be validated through JSON RPC Commands through HTTP. It has a request and response in JSN format.<\/p>\n<p>Note: the argument is case sensitive.<\/p>\n<p>&#8220;callsign&#8221;:&#8221;org.rdk.PluginTemplate&#8221;<\/p>\n<\/p>\n<div class=\"table-wrap\">\n\n\n<table class=\"relative-table wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col style=\"width: 19.99%\">\n\t\t\t\t\t\t\t<col style=\"width: 39.53%\">\n\t\t\t\t\t\t\t<col style=\"width: 28.11%\">\n\t\t\t\t\t\t\t<col style=\"width: 12.33%\">\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Function<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Request<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Response<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Remarks<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Activate controller<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a>&nbsp;&#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{ &#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;Controller.1.activate&#8221;, &#8220;params&#8221;:{&#8220;callsign&#8221;:&#8221;org.rdk.PluginTemplate&#8221;} }&#8217;&nbsp; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Deactivate controller<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a>&nbsp;&#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{ &#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;Controller.1.deactivate&#8221;, &#8220;params&#8221;:{&#8220;callsign&#8221;:&#8221;org.rdk.PluginTemplate&#8221;} }&#8217;&nbsp; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">getPluginStatus<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;org.rdk.PluginTemplate.1.getPluginTemplateStatus&#8221;}&#8217; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;connection status from plugin&#8221;:[&#8220;CONNECTED&#8221;],&#8221;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">getPluginTemplateList<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;org.rdk.PluginTemplate.1.getPluginTemplateList&#8221;}&#8217; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;Supported plugin list&#8221;:[&#8220;plug-A&#8221;,&#8221;plug-B&#8221;,&#8221;plug-C&#8221;,&#8221;plug-D&#8221;,&#8221;plug-E&#8221;],&#8221;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">getPluginTemplateInfo<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;org.rdk.PluginTemplate.1.getPluginTemplateInfo&#8221;, &#8220;params&#8221;:{&#8220;plugin_name&#8221;:&#8221;plug-A&#8221;}}&#8217; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;supportedTvResolutions&#8221;:[&#8220;xyz-plugin&#8221;,&#8221;no:430HT5&#8243;],&#8221;success&#8221;:true}}root@raspberrypi-rdk-mc:~#<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;event API when hdmi connected<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;org.rdk.PluginTemplate.1.getConnectedVideoDisplays&#8221;}&#8217;<br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;connectedVideoDisplays&#8221;:[&#8220;HDMI0&#8243;],&#8221;success&#8221;:true}}root@raspberrypi-rdk-mc:~#<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;event API when hdmi not connected<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;org.rdk.PluginTemplate.1.getConnectedVideoDisplays&#8221;}&#8217;<br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">&nbsp;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;connectedVideoDisplays&#8221;:[],&#8221;success&#8221;:true}}root@raspberrypi-rdk-mc:~#<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">root@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{ \"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"Controller.1.activate\", \"params\":{\"callsign\":\"org.rdk.PluginTemplate\"} }' \n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{ \"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"Controller.1.deactivate\", \"params\":{\"callsign\":\"org.rdk.PluginTemplate\"} }' \n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{\"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"org.rdk.PluginTemplate.1.getPluginTemplateStatus\"}'\n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"connection status from plugin\":[\"CONNECTED\"],\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{\"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"org.rdk.PluginTemplate.1.getPluginTemplateList\"}'\n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"Supported plugin list\":[\"plug-A\",\"plug-B\",\"plug-C\",\"plug-D\",\"plug-E\"],\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{\"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"org.rdk.PluginTemplate.1.getPluginTemplateInfo\", \"params\":{\"plugin_name\":\"plug-A\"}}'\n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"supportedTvResolutions\":[\"xyz-plugin\",\"no:430HT5\"],\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{\"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"org.rdk.PluginTemplate.1.getConnectedVideoDisplays\"}'\n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"connectedVideoDisplays\":[\"HDMI0\"],\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~# curl http:\/\/127.0.0.1:9998\/jsonrpc --header \"Content-Type: application\/json\" --request POST --data '{\"jsonrpc\":\"2.0\", \"id\":3, \"method\":\"org.rdk.PluginTemplate.1.getConnectedVideoDisplays\"}'\n{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"connectedVideoDisplays\":[],\"success\":true}}root@raspberrypi-rdk-mc:~#\nroot@raspberrypi-rdk-mc:~#<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>OUT OF PROCESS Plugin<\/strong><\/p>\n<p><span>Here the plugin is developed as out of process, which runs as a separate thread from WPEFramework. <\/span><span>Services each other or a particular service can be COMRPC ( for communication between plugins) or JSONRPC (for external communication). it has a web-based controller UI.<\/span><\/p>\n<h3 id=\"RDKVideoGuide-InsidePluginNamedirectoryInsidePluginNamedirectory\">Inside PluginName directory<span class=\"confluence-anchor-link conf-macro output-inline\" id=\"RDKVideoGuide-InsidePluginNamedirectory\" data-hasbody=\"false\" data-macro-name=\"anchor\"> <\/span><\/h3>\n<p>OutOfProcessPlugin\/<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; CMakeLists.txt<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; OutOfProcessPlugin.config<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; OutOfProcessPlugin.cpp<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; OutOfProcessPlugin.h<\/p>\n<p>&nbsp; &#9500;&#9472;&#9472; OutOfProcessPluginJsonRpc.cpp<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; OutOfProcessPlugin.json<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; Module.cpp<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; Module.h<br \/>&nbsp;&nbsp;&#9500;&#9472;&#9472; OutOfProcessPlugin.md<\/p>\n<\/p>\n<p><strong>&lt;PluginName&gt;.json<\/strong><\/p>\n<p>&nbsp;This file contains the plugin&#8217;s information like schema, information and interface json file. Here the outofprocess will be true, which indicates that the plugin run as a seperate process.<\/p>\n<p>&nbsp;eg: OutOfProcessPlugin.json<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">{\n\n&nbsp;\"locator\":\"libWPEFrameworkOutOfProcessPlugin.so\",\n\n&nbsp;\"classname\":\"OutOfProcessPlugin\",\n\n&nbsp;\"precondition\":[\n\n&nbsp; \"Platform\"\n\n&nbsp;],\n\n&nbsp;\"autostart\":true,\n\n&nbsp;\"configuration\":{\n\n&nbsp; \"root\":{\n\n&nbsp;&nbsp; \"outofprocess\":true\n\n&nbsp; }\n\n&nbsp;}\n\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>&lt;PluginName&gt;.config<\/strong><\/p>\n<p>.config files are files used to configure the parameters and initial settings for some computer programs.<\/p>\n<p>Here outofprocess is set to true, to make plugin as out of process plugin.<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">set (autostart true)\n\nset (preconditions Platform)\n\nmap()\n\n&nbsp;&nbsp;&nbsp; kv(outofprocess true)\n\nend()\n\nans(rootobject)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong><br \/>&lt;PluginName&gt;.h<\/strong><\/p>\n<p>Declare the plugin class in this which should contain all the structures, variables, and methods which are needed for plugin implementation.&nbsp;<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;namespace&nbsp;WPEFramework {\n\n&nbsp;&nbsp;namespace&nbsp;Plugin {\n\n&nbsp;&nbsp;&nbsp;class&nbsp;PluginName :&nbsp;public&nbsp;PluginHost::IPlugin,&nbsp;public&nbsp;PluginHost::IWeb,&nbsp;public&nbsp;PluginHost::JSONRPC {\n\n&nbsp;&nbsp;&nbsp;public:\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginName()\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: _skipURL(0)\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, _service(nullptr)\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, _subSystem(nullptr)\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RegisterAll();\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~PluginName()\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UnregisterAll();\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;---------------------------------------\n\n&nbsp;&nbsp;&nbsp;---------------------------------------\n\n&nbsp;&nbsp;}\n\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>&lt;PluginName&gt;.cpp<\/strong><\/p>\n<p>This class does contain all the definitions for the methods declared in the Plugin.h and those definitions should be defined inside the below namespace.&nbsp;<\/p>\n<p>The plugin should register using service registration MACRO as declared below :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;namespace&nbsp;WPEFramework {\n\n&nbsp;&nbsp;&nbsp;namespace&nbsp;Plugin {&nbsp;\n\n&nbsp;&nbsp;&nbsp;&nbsp;SERVICE_REGISTRATION(Plugin, 1, 0);\n\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n\n&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------\n\n&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span><br \/>To initialize and deinitialize or activate or deactivate handler for the plugin services :<\/span><\/p>\n<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">const&nbsp;string OutOfProcessPlugin::Initialize(PluginHost::IShell*&nbsp;\/* service *\/)\n\n&nbsp;&nbsp;&nbsp;&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;\/\/shared pointer initialized\n\n&nbsp;&nbsp;&nbsp;&nbsp;\/\/initialize external library\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;LOGINFO();\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;(string());\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;}\n\nvoid&nbsp;OutOfProcessPlugin::Deinitialize(PluginHost::IShell*&nbsp;\/* service *\/)\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;\/\/shared pointer deinitialized\n\n&nbsp;&nbsp;&nbsp;&nbsp;\/\/deinitialize external library\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;LOGINFO();\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>Process handler plugin services to receive request and sent responses based on the services :<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Core::ProxyType&lt;Web::Response&gt; OutOfProcessPlugin::Process(const Web::Request &amp;request)\n\n{\n\n&nbsp; Core::ProxyType&lt;Web::Response&gt; result(PluginHost::IFactories::Instance().Response());\n\n\n\n\n&nbsp; \/\/Handle the service request and send the responses\n\n&nbsp; -----------------\n\n&nbsp; -----------------\n\n&nbsp; return result;\n\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span><br \/>eg: refer OutOfProcessPlugin.cpp<\/span><\/p>\n<\/p>\n<p><strong>&lt;PluginNameJsonRpc&gt;.cpp&gt;<\/strong><\/p>\n<p>The PluginNameJsonRpc file contains the registration for methods and properties which are declared in PluginName.h<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">namespace&nbsp;WPEFramework {\n\n&nbsp;&nbsp;&nbsp;&nbsp;namespace&nbsp;Plugin { &nbsp;\n\n&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\/\/registration\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;void OutOfProcessPlugin::RegisterAll()\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\/\/ methods and properties declared in Plugin.h are registered here\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -------------------\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -------------------&nbsp;\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;void OutOfProcessPlugin::UnregisterAll()\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\n\n&nbsp;&nbsp;&nbsp;&nbsp;}\n\n}&nbsp;<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>CMakeLists.txt<\/strong><\/p>\n<p>Using the CMake utility this file contains the task needed to be done to make a plug-in. Also contains packages, libraries needed to compile, its path, and other plugin-in configuration option.<\/p>\n<p>This file contains a set of directives and instructions describing the project&#8217;s source files and targets (executable, library, or both).<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">set(PLUGIN_NAME OutOfProcessPlugin)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# to set a environment variable set(&lt;variable&gt; &lt;value&gt;)\n\nset(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME})\n\nfind_package(${NAMESPACE}Plugins REQUIRED)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# to Finds and loads settings from an external project.\n\n\n\n\n#Adds a library target called &lt;name&gt; to be built from the source files listed in the command invocation. The &lt;name&gt; corresponds to the logical target name and must be globally unique within a project.\n\nadd_library(${MODULE_NAME} SHARED\n\n&nbsp;&nbsp;&nbsp; OutOfProcessPlugin.cpp\n\n&nbsp;&nbsp;&nbsp; OutOfProcessPluginJsonRpc.cpp\n\n&nbsp;&nbsp;&nbsp; Module.cpp)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>The <strong>Code flow, Compilation and Install&nbsp;<\/strong>steps are similar to the PluginTemplate.<\/p>\n<p>The last step,<\/p>\n<p>Copy the Plugin.json (eg: OutOfProcessPlugin .json) file to &ldquo;\/etc\/WPEFramework\/plugins&rdquo; in Raspberry Pi<\/p>\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Copy the plugin library (libWPEFrameworkOutOfProcessPlugin.so) to &ldquo;\/usr\/lib\/wpeframework\/plugins&rdquo;<\/p>\n<p>so that the controller plugin identify it and list it in the WebUI ( controller UI ).<\/p>\n<h3 id=\"RDKVideoGuide-ControllerUI.1\">Controller UI<\/h3>\n<p>Controller UI is a web UI that can be launched from a host machine&#8217;s (machine under the same network where Rpi resides) browser.<\/p>\n<p><code>URL: http:\/\/&lt;IP address of the Target device&gt;:9998<\/code><\/p>\n<p><code><span class=\"confluence-embedded-file-wrapper confluence-embedded-manual-size\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/21\/2023\/09\/image2021-6-25_18-52-44.png\"><\/span><\/code><\/p>\n<h3 id=\"RDKVideoGuide-OutOfProcessPluginJSONRPCcommand\">OutOfProcessPlugin JSON RPC command<\/h3>\n<p>Each RDK Service can be validated through JSON RPC Commands through HTTP. It has a request and response in JSON format.<\/p>\n<p>Note: the argument is case sensitive.<\/p>\n<p>&#8220;callsign&#8221;:&#8221;OutOfProcessPlugin&#8221;<\/p>\n<\/p>\n<div class=\"table-wrap\">\n\n\n<table class=\"relative-table wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col style=\"width: 19.99%\">\n\t\t\t\t\t\t\t<col style=\"width: 39.53%\">\n\t\t\t\t\t\t\t<col style=\"width: 28.11%\">\n\t\t\t\t\t\t\t<col style=\"width: 12.33%\">\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Function<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Request<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Response<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Remarks<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Activate controller<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl http:\/\/localhost:9998\/jsonrpc<a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">127.0.0.1<\/a>http:\/\/localhost:9998\/jsonrpc &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{ &#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;Controller.1.activate&#8221;, &#8220;params&#8221;:{&#8220;callsign&#8221;:&#8221;OutOfProcessPlugin&#8221;} }&#8217;&nbsp; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Deactivate controller<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl http:\/\/localhost:9998\/jsonrpc<a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">127.0.0.1<\/a>http:\/\/localhost:9998\/jsonrpc &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{ &#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;Controller.1.deactivate&#8221;, &#8220;params&#8221;:{&#8220;callsign&#8221;:&#8221;OutOfProcessPlugin&#8221;} }&#8217;&nbsp; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:{&#8220;success&#8221;:true}}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Get fps<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;OutOfProcessPlugin.1.fps&#8221;}&#8217; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:32}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Get plugin id<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">curl <a href=\"http:\/\/127.0.0.1:9998\/jsonrpc\" class=\"rdk-inside-table\" rel=\"nofollow\">http:\/\/127.0.0.1:9998\/jsonrpc<\/a> &#8211;header &#8220;Content-Type: application\/json&#8221; &#8211;request POST &#8211;data &#8216;{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;, &#8220;id&#8221;:3, &#8220;method&#8221;:&#8221;OutOfProcessPlugin.1.getpluginid&#8221;}&#8217; <br>&nbsp;<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">{&#8220;jsonrpc&#8221;:&#8221;2.0&#8243;,&#8221;id&#8221;:3,&#8221;result&#8221;:6501}<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Interface with other RDK services<\/span><\/h3>\n<\/p>\n<\/div>\n<p><span>RDK components implemented as Thunder plugins are called as RDKServices.<\/span><span><span>&nbsp;I<\/span>t is developed based on the Thunder (WPE) Framework. Services each other or a particular service can be COMRPC ( for communication between plugins) or JSONRPC (for external communication).i.e.<\/span><\/p>\n<p><strong>COMRPC<\/strong><span>&nbsp;<\/span>is used to communicate between the plugins (out of process) or to communicate for larger data.<\/p>\n<p><strong>JSONRPC<\/strong><span>&nbsp;<\/span>is used to fetch\/update info to or from plugins externally (most of the plugins provide this in interface, similar to ReST API) also it can be used from applications.<\/p>\n<\/p>\n<h4 id=\"RDKVideoGuide-JSONRPC:\">JSONRPC:<\/h4>\n<p>For instance please see below Bluetooth plugin&#8217;s <strong>pair<\/strong> method with JSONRPC interface.<\/p>\n<h5 id=\"RDKVideoGuide-Events\"><u><strong>Events<\/strong><\/u><\/h5>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Event<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Description<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">BluetoothState: PAIRING_CHANGE<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Triggers onStatusChanged event when the device gets paired to given device ID.<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">BluetoothState: PAIRING_FAILED<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Triggers onRequestFailed event, when the device is unable to pair.<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<h5 id=\"RDKVideoGuide-Parameters\"><u><strong>Parameters<\/strong><\/u><\/h5>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Name<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Type<\/th>\n\t\t\t\t\t\t\t\t<th colspan=\"1\" class=\"confluenceTh\">Description<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">params<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">object<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">params.deviceID<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">string<\/td>\n\t\t\t\t\t\t\t\t<td colspan=\"1\" class=\"confluenceTd\">ID that is derived from the Bluetooth MAC address. 6 byte MAC value is packed into 8 byte with leading zeros for first 2 bytes<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<h5 id=\"RDKVideoGuide-Result\"><u><strong>Result<\/strong><\/u><\/h5>\n<div class=\"table-wrap\">\n\n\n<table class=\"wrapped confluenceTable\">\n\t\t\t\t\t\t<colgroup>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t\t<col>\n\t\t\t\t\t\t<\/colgroup>\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Name<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Type<\/th>\n\t\t\t\t\t\t\t\t<th class=\"confluenceTh\">Description<\/th>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">result<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">object<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\"><br><\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">result.success<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">boolean<\/td>\n\t\t\t\t\t\t\t\t<td class=\"confluenceTd\">Whether the request succeeded<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\n\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>Request<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">{\n    \"jsonrpc\": \"2.0\",\n    \"id\": 42,\n    \"method\": \"org.rdk.Bluetooth.1.pair\",\n    \"params\": {\n        \"deviceID\": \"61579454946360\"\n    }\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeHeader panelHeader pdl\"><b>Response<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">{\n    \"jsonrpc\": \"2.0\",\n    \"id\": 42,\n    \"result\": {\n        \"success\": true\n    }\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>For more details please refer :&nbsp;<a href=\"https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#pair-method\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#pair-method<\/a><\/p>\n<\/p>\n<h5 id=\"RDKVideoGuide-ThecorrespondingimplementationinThunderJSisgivenbelow:\"><u><strong><span>The corresponding implementation in ThunderJS is given below:<\/span><\/strong><\/u><\/h5>\n<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">   this.thunderJS.call('org.rdk.Bluetooth', 'pair', { deviceID: deviceIDval },\n \n      (err, result) =&gt; {\n \n        if (err) {\n \n          Log.info('n Bluetooth Pair error' + JSON.stringify(err))\n \n        } else {\n \n          Log.info('Pairing success' + JSON.stringify(result))\n \n        }\n \n      }\n \n    )<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>To know more about how to implement JSONRPC inerface using ThunderJS in JS environment please see <a href=\"https:\/\/github.com\/rdkcentral\/ThunderJS\/blob\/master\/readme.md\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/ThunderJS\/blob\/master\/readme.md<\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<div class=\" conf-macro output-inline\" data-hasbody=\"true\" data-macro-name=\"bgcolor\">\n<h3 class=\"wp-sub-header\"><span>Interface with Lightning apps<\/span><\/h3>\n<\/p>\n<\/div>\n<hr>\n<p><span>ThunderJS is used to make easy to make API calls to Thunder (WPEframework) over a Websocket connection. ThunderJS can also be used to listen to (and act upon) notifications broadcasted by Thunder. ThunderJS is an <\/span><em>isomorphic<\/em><span>&nbsp;library, which means it can be used in a browser environment as well as a NodeJS environment.<\/span><\/p>\n<p>Lightning is a Javascript TV app development framework based on NodeJS environment. So ThunderJS can be easily integrated to the Lightning apps.<\/p>\n<h4 id=\"RDKVideoGuide-AddingThunderJSdependencytopackage.json\"><strong>Adding ThunderJS dependency to package.json<\/strong><\/h4>\n<\/p>\n<p>ThunderJS dependencies can be added manually to the lightning projects by adding &lsquo;&#8221;ThunderJS&#8221;: &#8220;github:rdkcentral\/ThunderJS&#8221;,&rsquo; to the <em>package.json<\/em> under <em>&lsquo;devDependencies&rsquo;<\/em> and then run <em>&lsquo;npm install&rsquo;<\/em>.<\/p>\n<p><span>OR<\/span><\/p>\n<p>ThunderJS can be installed into your project via&nbsp;<em>NPM<\/em> command. Then the package.json will be updated with the thunder dependency &#8220;npm install github:rdkcentral\/ThunderJS&#8221;<\/p>\n<p>Snippet of package.json is given below .To use the ES6 syntax, we need add the Babel dependency also.<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">  }\n},\n\"devDependencies\": {\n \"@babel\/core\": \"^7.7.2\",\n \"ThunderJS\": \"github:rdkcentral\/ThunderJS\",\n \"babel-eslint\": \"^10.0.3\",\n \"dashjs\": \"^3.1.3\",\n \"eslint\": \"^6.6.0\",\n \"eslint-config-prettier\": \"^6.7.0\",\n \"eslint-plugin-prettier\": \"3.1.1\",\n \"hls.js\": \"^0.13.2\",\n \"husky\": \"^3.1.0\",\n \"lint-staged\": \"^9.4.3\"\n \"prettier\": \"^1.19.1\"\n  }\n}<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-ImportThunderJSdependencyinLightningscript\"><strong>Import ThunderJS dependency in Lightning script<\/strong><\/h4>\n<p><strong>&nbsp;<\/strong><\/p>\n<p>Next you can&nbsp;import&nbsp;the ThunderJS dependency into your own script like given below.<\/p>\n<p>import ThunderJS from &#8216;ThunderJS&#8217;,<\/p>\n<\/p>\n<h4 id=\"RDKVideoGuide-Initializingthelibrary\"><strong>Initializing the library<\/strong><\/h4>\n<p><strong>&nbsp;<\/strong><\/p>\n<p>The library can be initialised by passing the IP, port and other parameters mentioned below<\/p>\n<p><strong><br \/><\/strong><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">const config = {&nbsp; \n host: '192.168.1.100', \/\/ defaults to localhost,&nbsp; \n port: 2020, \/\/ defaults to 80&nbsp; endpoint: '\/api', \/\/ defaults to '\/jsonrpc'&nbsp; \n protocol: 'wss:\/\/', \/\/ defaults to 'ws:\/\/'&nbsp; \n subprotocols: 'notification', \/\/ WebSocket sub-protocols, defaults to 'notification'\n}\n const thunderJS = ThunderJS(config)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p>Example:<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">this.config = {\n\thost: '127.0.0.1',\n\tport:'9998'\n}\ntry {\n\tthis.thunderJS = ThunderJS(this.config)\n}\tcatch (err) {\n\tLog.error('Error in initialising the Thunder JS' , err)\n\n<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<h4 id=\"RDKVideoGuide-MakingAPICallsandreadresults\"><strong>Making API Calls and read results<\/strong><\/h4>\n<p><strong>&nbsp;<\/strong><\/p>\n<p>The library supports 2 ways of making API calls, depending on your coding style preferences.<\/p>\n<p><strong>Option 1 &#8211; Argument based<\/strong><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">const plugin = 'DeviceInfo'\n\nconst method = 'systeminfo'\n\nconst params = {\n\n&nbsp; foo: 'bar'\n\n}\n\nthunderJS.call(plugin, method, params)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>&nbsp;Option 2 &#8211; Object based<\/strong><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">const params = {\n\n&nbsp; foo: 'bar'\n\n}\n\nthunderJS.DeviceInfo.systeminfo(params)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><u><span>The result can be processed in two ways also:<\/span><\/u><\/p>\n<p><span><strong>Option 1 &#8211; Promise based<\/strong><\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">thunderJS.DeviceInfo.systeminfo()\n\n&nbsp; .then(result =&gt; {\n\n&nbsp;&nbsp;&nbsp; console.log('Success', result)\n\n&nbsp; }).catch(err =&gt; {\n\n&nbsp;&nbsp;&nbsp; console.error('Error', err)\n\n&nbsp; })<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span><strong>Option 1 &#8211; Callback based<\/strong><\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">thunderJS.DeviceInfo.systeminfo((err, result) =&gt; {\n\n&nbsp; if(err) {\n\n&nbsp;&nbsp;&nbsp; console.error('Error', err)\n\n&nbsp; }\n\n&nbsp; else {\n\n&nbsp;&nbsp;&nbsp; console.log('Success!', result)\n\n&nbsp; }\n\n})<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><span>Example for Argument based call for Bluetooth plugin is given below where the result is processed in callback based method<\/span><\/p>\n<p>Bluetooth plugin pair method &#8211; <a href=\"https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#pair-method\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#pair-method<\/a><\/p>\n<\/p>\n<p>Corresponding implementation in ThunderJS<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&nbsp;&nbsp;&nbsp;this.thunderJS.call('org.rdk.Bluetooth',&nbsp;'pair',&nbsp;{&nbsp;deviceID:&nbsp;deviceIDval&nbsp;},\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(err,&nbsp;result)&nbsp;=&gt;&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(err)&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.info('n&nbsp;Bluetooth&nbsp;Pair&nbsp;error'&nbsp;+&nbsp;JSON.stringify(err))\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.info('Pairing&nbsp;success'&nbsp;+&nbsp;JSON.stringify(result))\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;)<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<p><strong>&nbsp;<\/strong><\/p>\n<p><strong>Notifications<\/strong><\/p>\n<\/p>\n<p>Thunder (WPEframework) broadcasts notifications when events ocur in the system. However it will only broadcast those events that the client has subscribed to.<\/p>\n<p>ThunderJS makes it easy to subscribe to specific events, and execute a&nbsp;<em>callback-function<\/em>&nbsp;upon every notification of each event.<\/p>\n<\/p>\n<p>Example for notification event subscriptions is given below.<\/p>\n<\/p>\n<p>Bluetooth onDiscovered event &#8211;&nbsp; <a href=\"https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#ondiscovereddevice-event\" class=\"external-link\" rel=\"nofollow\">https:\/\/github.com\/rdkcentral\/rdkservices\/blob\/sprint\/2107\/Bluetooth\/doc\/BluetoothPlugin.md#ondiscovereddevice-event<\/a><\/p>\n<\/p>\n<p>Corresponding implementation in the Lightning App<\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\">\n<div class=\"codeContent panelContent pdl\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/**\n* Event listener to listen to device discovered\n*\/\nthis.thunderJS.on('org.rdk.Bluetooth','onDiscoveredDevice',notification =&gt;{\n\tLog.info('&lt;&lt;Device discovered event&gt;&gt;'+JSON.stringify(notification))\n})\n\n\n\/**<\/pre>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<div class=\"columnLayout single\" data-layout=\"single\">\n<div class=\"cell normal\" data-type=\"normal\">\n<div class=\"innerCell\">\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>This document guides users to perform the below activities on a Raspberry Pi (Rpi) platform [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":0,"parent":207,"menu_order":1,"comment_status":"open","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-2603","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RDK Video Guide - RDK Documentation Portal | Support<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RDK Video Guide - RDK Documentation Portal | Support\" \/>\n<meta property=\"og:description\" content=\"This document guides users to perform the below activities on a Raspberry Pi (Rpi) platform [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"RDK Documentation Portal | Support\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-25T05:18:37+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/\",\"url\":\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/\",\"name\":\"RDK Video Guide - RDK Documentation Portal | Support\",\"isPartOf\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/support\/#website\"},\"datePublished\":\"2023-06-27T06:38:16+00:00\",\"dateModified\":\"2025-03-25T05:18:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/developer.rdkcentral.com\/support\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Support\",\"item\":\"https:\/\/developer.rdkcentral.com\/support\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Articles\",\"item\":\"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"RDK Video Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/developer.rdkcentral.com\/support\/#website\",\"url\":\"https:\/\/developer.rdkcentral.com\/support\/\",\"name\":\"RDK Documentation Portal | Support\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/developer.rdkcentral.com\/support\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RDK Video Guide - RDK Documentation Portal | Support","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/","og_locale":"en_US","og_type":"article","og_title":"RDK Video Guide - RDK Documentation Portal | Support","og_description":"This document guides users to perform the below activities on a Raspberry Pi (Rpi) platform [&hellip;]","og_url":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/","og_site_name":"RDK Documentation Portal | Support","article_modified_time":"2025-03-25T05:18:37+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/","url":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/","name":"RDK Video Guide - RDK Documentation Portal | Support","isPartOf":{"@id":"https:\/\/developer.rdkcentral.com\/support\/#website"},"datePublished":"2023-06-27T06:38:16+00:00","dateModified":"2025-03-25T05:18:37+00:00","breadcrumb":{"@id":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/rdk-video-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/developer.rdkcentral.com\/support\/"},{"@type":"ListItem","position":2,"name":"Support","item":"https:\/\/developer.rdkcentral.com\/support\/"},{"@type":"ListItem","position":3,"name":"Articles","item":"https:\/\/developer.rdkcentral.com\/support\/support\/articles\/"},{"@type":"ListItem","position":4,"name":"RDK Video Guide"}]},{"@type":"WebSite","@id":"https:\/\/developer.rdkcentral.com\/support\/#website","url":"https:\/\/developer.rdkcentral.com\/support\/","name":"RDK Documentation Portal | Support","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/developer.rdkcentral.com\/support\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/pages\/2603","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/comments?post=2603"}],"version-history":[{"count":79,"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/pages\/2603\/revisions"}],"predecessor-version":[{"id":10351,"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/pages\/2603\/revisions\/10351"}],"up":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/pages\/207"}],"wp:attachment":[{"href":"https:\/\/developer.rdkcentral.com\/support\/wp-json\/wp\/v2\/media?parent=2603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}