You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 43 Next »

<work in progress>

Before you begin


RDK is an open source code project distributed through industry standard open source licenses e.g. Apache 2.0. This Document explains how users can create a build for RPI/reference platform, bring it up in target device and then create and run a sample lightning app  

Nice to have the below Skills

Basic skills needed by a user to use the current documentation

  • Familiar with Linux based platforms
  • Familiar with Yocto
  • Familiar with RDK basics
  • Knowledge in using Raspberry Pi
  • Experience in setting up boards

Prerequisites

Requirement

Yocto 2.2 (Morty)

Yocto 3.1 LTS (Dunfell)

Linux PC

32/64 bit Ubuntu 16.04 LTS

Precise supported distributions and versions are here

64 bit Ubuntu 18.04 LTS

Precise supported distributions and versions are here

Free HDD Space

Minimum 100GB Free Memory

Minimum 100GB Free memory space

Oracle Virtual Box

5.0.40 or higher

-

Wireless Adapter

Brand Name: Tenda ralink & Model Number:W311MI

TP-Link Archer T4U AC 1200

-

USB to Ethernet Switch

To connect with Ethernet Switch & Multiple Clients


Host Tools version

Git 1.8.3.1 or greater

tar 1.24 or greater

Python 2.7.3

Git 1.8.3.1 or greater

tar 1.28 or greater

Python 3.5.0 or greater

RaspberryPI or Reference boardAccess to build binaries requiredAccess to build binaries required
PeripheralsTVTV

Environment Rpi 3b+/ IPSTB ref box


Build Setup

build setup
repo init -u https://code.rdkcentral.com/r/manifests -b dunfell -m rdkv-nosrc.xml
repo sync -j `nproc` --no-clone-bundle --no-tags

Build basic image for Rpi

Image build
MACHINE=raspberrypi-rdk-hybrid source meta-cmf-raspberrypi/setup-environment
bitbake rdk-generic-hybrid-wpe-image

Build basic image IPSTB ref box

Need to confirm whether to have IPSTB or not


Code checkout:


$ mkdir <RDK_DIR>
$ cd <RDK_DIR>
$ repo init -u https://code.rdkcentral.com/r/collaboration/soc/amlogic/aml-accel-manifests -b rdk-next -m rdk-firebolt-dunfell-ref-sc2-k54-202109.xml 
$ repo sync -j4 --no-clone-bundle
 
or
 
$ repo init -u https://code.rdkcentral.com/r/collaboration/soc/amlogic/aml-accel-manifests -b rdk-next -m rdk-firebolt-dunfell-ref-sc2-k54-202109.xml --repo-branch=v2.9
$ repo sync -j4 --no-clone-bundle

Build image:


$ cd $(RDK_DIR)
$ export LOCAL_BUILD=1
$ source meta-amlogic/aml-setenv.sh
 
You're building on Linux
Lunch menu...pick a combo:
 
1.      mesons4-lib32-ap222
2.      mesons4-lib32-ap223
3.      mesons4-lib32-ap229
4.      mesons4-lib32-aq222
5.      mesons4-lib32-aq223
6.      mesonsc2-5.4-lib32-ah212
7.      mesonsc2-5.4-lib32-ah212-hybrid
8.      mesonsc2-5.4-lib32-ah212-vmx
9.      mesonsc2-5.4-lib32-ah219
10.     mesonsc2-5.4-lib32-ah232
11.     mesonsc2-5.4-lib32-ah232-irdeto
12.     mesonsc2-5.4-lib32-ah232-nagra
13.     mesonsc2-5.4-lib32-ah232-synamedia
 
Which would you like? [2] 4
 
$ bitbake lib32-rdk-generic-mediaclient-image


Other way:


$ repo init --no-clone-bundle -u https://code.rdkcentral.com/r/collaboration/oem/skyworth/skyworth-aml905X2-manifests -b rdk-next -m sc2-rdkservices-restricted.xml --repo-branch=v2.9
$ repo sync -j 32
$ source meta-rdk-skyworth-hx4x/setup-environment --hp44h-rdk --restricted --read-write
$ bitbake lib32-skyworth-generic-mediaclient-image

Flash image and bring up Rpi <In Progress>


1. Insert an SD card in the SD card port of the USB SD card reader (or Laptop).

     Prefer to use 32gb sd card and there should be minimum 12gb free space available in the device .

2. Verify that the SD card has been detected by executing either of the commands listed below

$lsblk
$sudo fdisk –l 

 3. Type the following command to ensure that the partitions, if present, on the SD card are not mounted

$mount

4. Repeat the below command to unmount all the mounted partition present on the SD card.

$unmount <partition-mountpoint>

5. Execute the following command to flash the image on the SD card

Flash Command
sudo dd if=<path to ImageName.rpi-sdimg> of=<path to SD card space> bs=4M
Example:
$ sudo dd if=rdk-generic-broadband-image-raspberrypi-rdk-broadband.rpi-sdimg of=/dev/sdb bs=4M

6. Increase size of “ext3” File system based partition of SDCard. The increased partition is required to copy media files for streaming. Any tools/utilities can be used to alter partition size. The explanations captured below are using “Gparted” a linux-based tool to alter partition size.  

Follow instruction given below:- 

  • Install ‘Gparted’ using below instruction:- 
$sudo apt-get install gparted

Once Gparted installed successfully. Open ‘Gparted’ with root privileges:-


“Gparted” graphical window shall appear.

  • Select “ext3” File System based partition of SDCard to alter partition size:-

 


  • Extend the ext3 partition to maximum available space in the 32gb sd card .



  • Click on “apply all operations” to modify the size:-


7. Repeat the below command to unmount all the mounted partition present on the SD card.

$unmount <partition-mountpoint> 

8. Remove the SD card and insert it to the Raspberry Pi SD card slot 

9. Similarly flash the mediaclient image on another SD Card and insert it to another Raspberry Pi SD Card slot 

10. Bring up the device



Flash image and bring up IPSTB ref box


Need to confirm whether to have IPSTB or not


1) Using Burning tool
Keep pressing enter to stop at sc2_hp44h# 
Connect the usb-usb connector and launch Aml_Burn_Tool V3. 
sc2_hp44# run update
Burning tool should show connected. Select image and flash.
2) MfrUtils
Download the image to /data/ path on the device.
mfrUtil -u /data/aml_upgrade_package.img
3) Using firmware update plugin.
Please refer to Firmware Control plugin methods to flash through thunder plugin.
4) USB upgrade
Copy the aml_sdc_burn.ini and image to USB. 
Connect USB to the device and stop the device at the boot prompt. ie sc2_hp44h#
usb_burn aml_sdc_burn.ini
NOTE: Please reach out to Skyworth for aml_sdc_burn.ini

Flashing through xconf :

https://wiki.rdkcentral.com/display/RDK/Firmware+Upgrade+through+XCONF+Server

ToDo: Alanyse what to add from the above link

Yocto recipe structure of relevant components - wpeframework and RDKServices

What is Wpeframework?

ToDo

What is RDKServices?

ToDo

Explain layer structures in RDK-V build

ToDo

../meta-cmf-video/recipes-extended/rdkservices/rdkservices_git.bbappend
../meta-rdk-broadcom-generic-rdk/meta-brcm-refboard/meta-rdk-video/recipes-extended/rdkservices/rdkservices_git.bbappend
../meta-rdk-bsp-emulator/recipes-extended/rdkservices/rdkservices_git.bbappend
../meta-rdk-ext/recipes-extended/rdkservices/rdkservices_%.bbappend
../meta-rdk-oem-comm-bcm-accel/meta-vip7802/recipes-extended/rdkservices/rdkservices_git.bbappend
../meta-rdk-oem-comm-bcm-accel/meta-vip5202w/recipes-extended/rdkservices/rdkservices_git.bbappend
../meta-rdk-soc-broadcom/meta-brcm/recipes-extended/wpe-framework/rdkservices_git.bbappend
../meta-rdk-soc-broadcom/meta-brcm/recipes-extended/wpe-framework/rdkservices-comcast_git.bbappend
../meta-rdk-video/recipes-extended/rdkservices/rdkservices_git.bb


Setup and Develop Thunder plugin


Steps involved in implementing new RDK services Plug-In

RDK components implemented as Thunder plugins are called as RDKServices. it is  developed based on the Thunder (WPE) Framework. Services each other or a particular service can be COMRPC ( for (communication between plugins) or RPC (for external communication). it has a web-based controller UI.

Reference : https://github.com/rdkcentral/rdkservices/pull/960 

 In RDK services -plugins workspace:

 Cloned from https://github.com/rdkcentral/rdkservices

	$ git clone https://github.com/rdkcentral/rdkservices

Inside PluginName directory

  1.  <PluginName>.json : This file contains the plugin's information like schema, information and interface json file.
    1. PluginTemplate.json
    2. DeviceInfo.json
  2.  CmakeLists.txt:  CMAKE based configuration file which contains a set of directives and instructions describing the project's source files and targets. This is used to compile the Plug-in code to generate the plugin library(Shared library by default; “.so”). External dependencies can be included/linked to the target with the help of CMakeLists.txt configurations.
  3. Module.h: This header file includes the support for JSON request, response, logging etc...
  4. Module.cpp: This file is used to declare the module name for the Plug-in. This file contains the plugin's information like schema, information and interface json file (defined earlier).
  5. <PluginName>.config: This file is used to set configurations of the Plug-in . Ex:- set (autostart true) - Used to make the Plug-in to start automatically along with wpeframework daemon
  6. <PluginName>.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,
  7. <PluginName>.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.
  8. Cmake / (directory) :
      

PluginTemplate/
  ├── CMakeLists.txt
  ├── PluginTemplate.config
  ├── PluginTemplate.cpp
  ├── PluginTemplate.h
  ├── PluginTemplate.json
  ├── Module.cpp
  ├── Module.h
  ├── README.md
  ├── cmake
  |   ├── FindDS.cmake
  │   └── FindIARMBus.cmake
  └── doc
   └── PluginTemplate.md

<PluginName>.json

 This file contains the plugin's information like schema, information and interface json file.

Syntax :

   {
    {
    "$schema": "plugin.schema.json",
    "info": {
    "title": "Plugin Name Plugin",
    "callsign": "PluginName",
    "locator": "libWPEFrameworkPluginName.so",
    "status": "production",
    "description": "The PluginName plugin allows retrieving of various plugin-related information.",
    "version": "1.0"
     },
     "interface": {
    "$ref": "{interfacedir}/PluginName.json#"
     }
   }

eg: PluginTemplate.json

 {
     "locator":"libWPEFrameworkPluginTemplate.so",
     "classname":"PluginTemplate",
     "precondition":[
      "Platform"
     ],
     "callsign":"org.rdk.PluginTemplate",
     "autostart":false
 } 

<PluginName>.config

.config files are files used to configure the parameters and initial settings for some computer programs.

set (autostart false)                       #we are setting autostart condition disable 
set (preconditions Platform) 
set (callsign "org.rdk.PluginTemplate") 	#The callsign name was given to an instance of a plugin. 

#One plugin can be instantiated multiple times. but each instance, the instance-name "callsign" must be unique. here we using org.rdk.PluginTemplate. 

<PluginName>.h

Declare the plugin class in this which should contain all the structures, variables, and methods which are needed for plugin implementation. 

 namespace WPEFramework {
  namespace Plugin {
   
   class PluginName : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC {
   public:
     PluginName()
      : _skipURL(0)
      , _service(nullptr)
      , _subSystem(nullptr)
     {
      RegisterAll();
     }
  
     virtual ~PluginName()
     {
      UnregisterAll();
     }
   }
   ---------------------------------------
   ---------------------------------------
  }
}

eg: PluginTemplate.h

for more information refer PluginTemplate.h 

<PluginName>.cpp

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. 

The plugin should register using service registration MACRO as declared below :

  namespace WPEFramework {
   namespace Plugin {  
    SERVICE_REGISTRATION(Plugin, 1, 0);
    ---------------------------------------
    ---------------------------------------
    ---------------------------------------
   }
  }

 To initialize and deinitialize or activate or deactivate handler for the plugin services :

const string PluginTemplate::Initialize(PluginHost::IShell* /* service */)
	{
	//shared pointer initialized
	//initialize external library
        LOGINFO();
        return (string());
        }
void PluginTemplate::Deinitialize(PluginHost::IShell* /* service */)
        {
 	//shared pointer deinitialized
	//deinitialize external library
        LOGINFO();
        }

eg:

namespace WPEFramework {
    namespace Plugin {  
         SERVICE_REGISTRATION(Plugin, 1, 0);
                
          //registration
          //All the methods declared in Plugin.h should be registered here
                
          //initialize and deinitialize the handlers for the plug-in service
                
          //All the methods declared in Plugin.h should be defined here
                              
    }
} 

CMakeLists.txt

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.

This file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both).

set(PLUGIN_NAME PluginTemplate)                          # to set a environment variable set(<variable> <value>)
set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME})
find_package(${NAMESPACE}Plugins REQUIRED)               # to Finds and loads settings from an external project.

#Adds a library target called <name> to be built from the source files listed in the command invocation. The <name> corresponds to the logical target name and must be globally unique within a project.
add_library(${MODULE_NAME} SHARED
        PluginTemplate.cpp
        Module.cpp
        ../helpers/utils.cpp)

Code flow

  • Enable or disable the plug-in flag in the recipe file.
  • Add this flag into the main CMakeLists.txt file present in the rdkservice.
  • It will invoke CMakeLists file present in the <plugin name>/ (eg: PluginTemplate/CMakeLists.txt).
  • When this file started to execute it finds dependencies, packages. it compiled and generate .so file.

To add plugin in rdkservices CMakeLists.txt

In rdkservices directory open CmakeLists.txt :

	$ vi CmakeLists.txt

add these lines ( by default its disabled ) :

    if(PLUGIN_PLUGINTEMPLATE)
    	add_subdirectory(PluginTemplate)
    endif()

 it will invoke your CMakeLists.txt file present in your plugin directory.

Compilation and Install

To include plugintemplate plugin in build sequence, Open rdkservices recipe file and add below line. By default; its configured to be disabled while building rdkservices.

            $ vi meta-rdk-video/recipes-extended/rdkservices/rdkservices_git.bb
PACKAGECONFIG[plugintemplate]      = " -DPLUGIN_PLUGINTEMPLATE=OFF,-DPLUGIN_PLUGINTEMPLATE=ON, "  

To include the plugin in rdkservises build; add the same in packageconfig in rdkservices recipe:

              PACKAGECONFIG += " plugintemplate"

to compile and install in build directory :

	$ bitbake -c compile -f rdkservices

once build complete copy .json, .so file into raspberrypi.

Copy the Plugin.json (eg: PluginTemplate.json) file to “/etc/WPEFramework/plugins” in raspberrypi

          Copy the plugin library (libWPEFrameworkPluginTemplate.so) to “/usr/lib/wpeframework/plugins”

so that the controller plugin identify it and list it in the WebUI ( controller UI ).

Controller UI

Controller UI is a web UI that can be launched from a host machine's (machine under the same network where RPi resides) browser. This UI can be loaded with the RPi box's IP address with Thunder's port number configured (here). RDKServices uses 9998 as port.


URL: http://<IP address of the Target device>:9998


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.


PluginTemplate JSON RPC command

Each RDK Service can be validated through JSON RPC Commands through HTTP. It has a request and response in JSN format.

Note: the argument is case sensitive.

"callsign":"org.rdk.PluginTemplate"


FunctionRequestResponseRemarks
Activate controllercurl 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"} }' 
 
{"jsonrpc":"2.0","id":3,"result":{"success":true}}
Deactivate controllercurl 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"} }' 
 
{"jsonrpc":"2.0","id":3,"result":{"success":true}}
getPluginStatuscurl 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"}'
 
{"jsonrpc":"2.0","id":3,"result":{"connection status from plugin":["CONNECTED"],"success":true}}
getPluginTemplateListcurl 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"}'
 
{"jsonrpc":"2.0","id":3,"result":{"Supported plugin list":["plug-A","plug-B","plug-C","plug-D","plug-E"],"success":true}}
getPluginTemplateInfocurl 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"}}'
 
{"jsonrpc":"2.0","id":3,"result":{"supportedTvResolutions":["xyz-plugin","no:430HT5"],"success":true}}root@raspberrypi-rdk-mc:~#
 event API when hdmi connected 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"}'
 
 {"jsonrpc":"2.0","id":3,"result":{"connectedVideoDisplays":["HDMI0"],"success":true}}root@raspberrypi-rdk-mc:~#
 event API when hdmi not connected 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"}'
 
 {"jsonrpc":"2.0","id":3,"result":{"connectedVideoDisplays":[],"success":true}}root@raspberrypi-rdk-mc:~#




OUT OF PROCESS Plugin

Here the plugin is developed as out of process, which runs as a separate thread from WPEFramework. 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.

Inside PluginName directory

OutOfProcessPlugin/
  ├── CMakeLists.txt
  ├── OutOfProcessPlugin.config
  ├── OutOfProcessPlugin.cpp
  ├── OutOfProcessPlugin.h

  ├── OutOfProcessPluginJsonRpc.cpp
  ├── OutOfProcessPlugin.json
  ├── Module.cpp
  ├── Module.h
  ├── OutOfProcessPlugin.md


<PluginName>.json

 This file contains the plugin'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.

 eg: OutOfProcessPlugin.json

{

 "locator":"libWPEFrameworkOutOfProcessPlugin.so",

 "classname":"OutOfProcessPlugin",

 "precondition":[

  "Platform"

 ],

 "autostart":true,

 "configuration":{

  "root":{

   "outofprocess":true

  }

 }

}


<PluginName>.config

.config files are files used to configure the parameters and initial settings for some computer programs.

Here outofprocess is set to true, to make plugin as out of process plugin.


set (autostart true)

set (preconditions Platform)

map()

    kv(outofprocess true)

end()

ans(rootobject)


<PluginName>.h

Declare the plugin class in this which should contain all the structures, variables, and methods which are needed for plugin implementation. 

 namespace WPEFramework {

  namespace Plugin {

   class PluginName : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC {

   public:

     PluginName()

      : _skipURL(0)

      , _service(nullptr)

      , _subSystem(nullptr)

     {

      RegisterAll();

     }

     virtual ~PluginName()

     {

      UnregisterAll();

     }

   }

   ---------------------------------------

   ---------------------------------------

  }

}


<PluginName>.cpp

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. 

The plugin should register using service registration MACRO as declared below :

  namespace WPEFramework {

   namespace Plugin { 

    SERVICE_REGISTRATION(Plugin, 1, 0);

    ---------------------------------------

    ---------------------------------------

    ---------------------------------------

   }

  }

To initialize and deinitialize or activate or deactivate handler for the plugin services :

const string OutOfProcessPlugin::Initialize(PluginHost::IShell* /* service */)

    {

    //shared pointer initialized

    //initialize external library

        LOGINFO();

        return (string());

        }

void OutOfProcessPlugin::Deinitialize(PluginHost::IShell* /* service */)

        {

    //shared pointer deinitialized

    //deinitialize external library

        LOGINFO();

        }


Process handler plugin services to receive request and sent responses based on the services :

Core::ProxyType<Web::Response> OutOfProcessPlugin::Process(const Web::Request &request)

{

  Core::ProxyType<Web::Response> result(PluginHost::IFactories::Instance().Response());


  //Handle the service request and send the responses

  -----------------

  -----------------

  return result;

}

eg: refer OutOfProcessPlugin.cpp


<PluginNameJsonRpc>.cpp>

The PluginNameJsonRpc file contains the registration for methods and properties which are declared in PluginName.h

namespace WPEFramework {

    namespace Plugin {  

          //registration

         void OutOfProcessPlugin::RegisterAll()

          {

               // methods and properties declared in Plugin.h are registered here

                  -------------------

                  ------------------- 

          }

         void OutOfProcessPlugin::UnregisterAll()

         {

         }                        

    }


CMakeLists.txt

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.

This file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both).

set(PLUGIN_NAME OutOfProcessPlugin)                          # to set a environment variable set(<variable> <value>)

set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME})

find_package(${NAMESPACE}Plugins REQUIRED)               # to Finds and loads settings from an external project.


#Adds a library target called <name> to be built from the source files listed in the command invocation. The <name> corresponds to the logical target name and must be globally unique within a project.

add_library(${MODULE_NAME} SHARED

    OutOfProcessPlugin.cpp

    OutOfProcessPluginJsonRpc.cpp

    Module.cpp)


The Code flow, Compilation and Install steps are similar to the PluginTemplate.

The last step,

Copy the Plugin.json (eg: OutOfProcessPlugin .json) file to “/etc/WPEFramework/plugins” in raspberrypi

          Copy the plugin library (libWPEFrameworkOutOfProcessPlugin.so) to “/usr/lib/wpeframework/plugins”

so that the controller plugin identify it and list it in the WebUI ( controller UI ).

Controller UI

Controller UI is a web UI that can be launched from a host machine's (machine under the same network where RPi resides) browser.

URL: http://<IP address of the Target device>:9998

OutOfProcessPlugin JSON RPC command

Each RDK Service can be validated through JSON RPC Commands through HTTP. It has a request and response in JSON format.

Note: the argument is case sensitive.

"callsign":"OutOfProcessPlugin"


FunctionRequestResponseRemarks
Activate controllercurl 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":"OutOfProcessPlugin"} }' 
 
{"jsonrpc":"2.0","id":3,"result":{"success":true}}
Deactivate controllercurl 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":"OutOfProcessPlugin"} }' 
 
{"jsonrpc":"2.0","id":3,"result":{"success":true}}
Get fpscurl http://127.0.0.1:9998/jsonrpc --header "Content-Type: application/json" --request POST --data '{"jsonrpc":"2.0", "id":3, "method":"OutOfProcessPlugin.1.fps"}'
 
{"jsonrpc":"2.0","id":3,"result":32}
Get plugin idcurl http://127.0.0.1:9998/jsonrpc --header "Content-Type: application/json" --request POST --data '{"jsonrpc":"2.0", "id":3, "method":"OutOfProcessPlugin.1.getpluginid"}'
 
{"jsonrpc":"2.0","id":3,"result":6501}

Interface with other RDK services


 how the interfaces COMRPC and JSONRPC used and its details

Interface with Lightning apps


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 isomorphic library, which means it can be used in a browser environment as well as a NodeJS environment.

Lightning is a Javascript TV app development framework based on NodeJS environment. So ThunderJS can be easily integrated to the Lightning apps.

Adding ThunderJS dependency to package.json


ThunderJS dependencies can be added manually to the lightning projects by adding ‘"ThunderJS": "github:rdkcentral/ThunderJS",’ to the package.json under ‘devDependencies’ and then run ‘npm install’.

OR

ThunderJS can be installed into your project via NPM command. Then the package.json will be updated with the thunder dependency "npm install github:rdkcentral/ThunderJS"

Snippet of package.json is given below .To use the ES6 syntax, we need add the Babel dependency also.




Import ThunderJS dependency in Lightning script

 

Next you can import the ThunderJS dependency into your own script like given below.

import ThunderJS from 'ThunderJS',


Initializing the library

 

The library can be initialised by passing the IP, port and other parameters mentioned below


const config = {  
 host: '192.168.1.100', // defaults to localhost,  
 port: 2020, // defaults to 80  endpoint: '/api', // defaults to '/jsonrpc'  
 protocol: 'wss://', // defaults to 'ws://'  
 subprotocols: 'notification', // WebSocket sub-protocols, defaults to 'notification'
}
 const thunderJS = ThunderJS(config)


Example:

 


Making API Calls and read results

 

The library supports 2 ways of making API calls, depending on your coding style preferences.

Option 1 - Argument based

 

const plugin = 'DeviceInfo'

const method = 'systeminfo'

const params = {

  foo: 'bar'

}

thunderJS.call(plugin, method, params)

The result can be processed in two ways also

thunderJS.DeviceInfo.systeminfo()

  .then(result => {

    console.log('Success', result)

  }).catch(err => {

    console.error('Error', err)

  })



Example for Argument based call for Bluetooth plugin is given below where the result is processed in callback based method

Bluetooth plugin pair method - https://github.com/rdkcentral/rdkservices/blob/sprint/2107/Bluetooth/doc/BluetoothPlugin.md#pair-method


Corresponding implementation in ThunderJS

   this.thunderJS.call('org.rdk.Bluetooth', 'pair', { deviceID: deviceIDval },

      (err, result) => {

        if (err) {

          Log.info('\n Bluetooth Pair error' + JSON.stringify(err))

        } else {

          Log.info('Pairing success' + JSON.stringify(result))

        }

      }

    )

 

Notifications


Thunder (WPEframework) broadcasts notifications when events ocur in the system. However it will only broadcast those events that the client has subscribed to.

ThunderJS makes it easy to subscribe to specific events, and execute a callback-function upon every notification of each event.


Example for notification event subscriptions is given below.


Bluetooth onDiscovered event -  https://github.com/rdkcentral/rdkservices/blob/sprint/2107/Bluetooth/doc/BluetoothPlugin.md#ondiscovereddevice-event


Corresponding implementation in the Lightning App




Build Setup Instructions


Hardware requirements and setting up the host environment and Downloading Source Code is explained below.

Setting up the Host Environment

Prerequisites


Requirement

Yocto 2.2 (Morty)

Yocto 3.1 LTS (Dunfell)

Linux

32/64 bit Ubuntu 16.04 LTS

Precise supported distributions and versions are here

64 bit Ubuntu 18.04 LTS

Precise supported distributions and versions are here

Free HDD Space

Minimum 100GB Free Memory

Minimum 100GB Free memory space

Oracle Virtual Box

5.0.40 or higher

-

Wireless Adapter

Brand Name: Tenda ralink & Model Number:W311MI

TP-Link Archer T4U AC 1200

-

USB to Ethernet Switch

To connect with Ethernet Switch & Multiple Clients


Host Tools version

Git 1.8.3.1 or greater

tar 1.24 or greater

Python 2.7.3

Git 1.8.3.1 or greater

tar 1.28 or greater

Python 3.5.0 or greater

Install the following packages for setting up the host VM

The instructions provided below are meant to be executed via the command line on an Ubuntu machine


for yocto 2.2 (morty)
# essential packages installation
# super user mode is required
 
# major essential packages
sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib g++-multilib build-essential chrpath socat bison curl
# supportive packages
sudo apt-get install libfile-slurp-perl libncurses-dev autoconf flex doxygen libtool automake libpcre3-dev zlib1g-dev libbz2-dev subversion minicom putty libssl-dev rpm python-pexpect python-svn python-argparse vim tofrodos meld dos2unix cmake uuid-dev ruby transfig libglib2.0-dev xutils-dev lynx-cur gperf autopoint python-dulwich python-dev openjdk-7-jre


Note : Please note openjdk-7-jre package is not available for Ubuntu-16.04 anymore. Presumably openjdk-8-jre should be used instead.


for yocto 3.1 (dunfell)
# essential packages installation
# super user mode is required
 
# major essential packages
sudo 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

Configure bash as default command interpreter for shell scripts


sudo dpkg-reconfigure dash

Select “No”
To choose bash, when the prompt asks if you want to use dash as the default system shell - select “No”

Configure Git

Upgrade your Git version to 1.8.x or higher

On Ubuntu 16.04 LTS, if you are unable to upgrade your git version using apt-get, then follow the below steps in order to upgrade 


sudo apt-get install python-software-properties
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git

Once git is installed, configure your name and email using the below commands


# review your existing configuration
git config --list --show-origin
 
# configure user name and email address
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
 
# configure git cookies. Needed for Gerrit to only contact the LDAP backend once.
git config --global http.cookieFile /tmp/gitcookie.txt
git config --global http.saveCookies true

Configure repo

In order to use Yocto build system, first you need to make sure that repo is properly installed on the machine:

# create a bin directory
mkdir ~/bin
export PATH=~/bin:$PATH
 
# Download the repo tool and ensure that it is executable
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo


Credential configuration

Note: it is also recommended to put credentials in .netrc when interacting with the repo.

A sample .netrc file is illustrated below

machine code.rdkcentral.com

    login <YOUR_USERNAME>

    password <YOUR_PASSWORD>

Downloading Source Code & Building

Downloading Source Code

Following commands fetch the source code using repo tool

$ mkdir <Directory-Name> && cd <Directory-Name>

Please use the following repo init command

$ repo init -u https://user@code.rdkcentral.com/r/manifests -m manifest.xml -b <branch_name>

Examples :

repo init -u https://code.rdkcentral.com/r/manifests -m rdkb.xml -b rdkb-20180527

repo init -u https://code.rdkcentral.com/r/manifests -m rdkb.xml -b master

repo init -u https://code.rdkcentral.com/r/manifests -m rdkb.xml -b morty


$ repo sync -j`nproc` --no-clone-bundle

Building

$ source <setup-environment>

The above step configures and sets up your directory to start an appropriate build.

There are different kinds of builds listed. Please read the options and select the number of the build you need.

1) meta-rdk-bsp-emulator/conf/machine/qemuarmbroadband.conf
2) meta-rdk-bsp-emulator/conf/machine/qemux86broadband.conf
3) meta-rdk-bsp-emulator/conf/machine/qemux86hyb.conf
4) meta-rdk-bsp-emulator/conf/machine/qemux86mc.conf
5) openembedded-core/meta/conf/machine/qemuarm.conf
6) openembedded-core/meta/conf/machine/qemux86-64.conf
7) openembedded-core/meta/conf/machine/qemux86.conf

Next, you need to initiate the build using the following command:

$ bitbake <image-name>

On Successful build, the ROOTFS (in vmdk format) would be available at the following reference location based on the build type :

-$ {HOME}/emulator/build-qemux86broadband/tmp/deploy/images/qemux86broadband/rdk-generic-broadband-image-qemux86broadband-<timestamp>.vmdk

Example :  

…/build-qemux86broadband/tmp/deploy/images/qemux86broadband/rdk-generic-broadband-image-qemux86broadband-20160217080610.vmdk


<From Environment RPI section>


Image Build

Media Client

Instruction to build media client image

image build
MACHINE=raspberrypi-rdk-mc source meta-cmf-raspberrypi/setup-environment
bitbake rdk-generic-mediaclient-wpe-image

Hybrid Gateway

Instruction to build hybrid gateway image

image build
MACHINE=raspberrypi-rdk-hybrid source meta-cmf-raspberrypi/setup-environment
bitbake rdk-generic-hybrid-wpe-image

Hybrid Gateway with Operator Ref. App

Instruction to build hybrid gateway image with operator reference application

image build
MACHINE=raspberrypirdkhybrefapp source meta-cmf-raspberrypi/setup-environment
bitbake rdk-generic-hybrid-refapp-image


The generated image resides under the directory build-<MACHINE>/tmp/deploy/images/<MACHINE> of the Yocto workspace



Flash Procedure

The micro SD card should not have any partition while flashing the image. The complete memory of the card should be free

# of - output file (the device file for the inserted micro SD card
bzcat <IMAGE_NAME>-<MACHINE>.wic.bz2 | sudo dd of=/dev/sdb bs=4M iflag=fullblock oflag=direct conv=fsync

Known Issue

  • Cobalt is crashed upon launching over RDK Shell


<From build basic image RPI section>




Flashing Procedure

The image file will be generated under build-<MACHINE>/tmp/deploy/images/<MACHINE> directory.

eg: dsrava434@dvm-yocto3-docker-dsrava434:~/varsha/build-raspberrypi-rdk-ipmc/tmp/deploy/images/raspberrypi-rdk-ipmc$ pwd

/home/dsrava434/varsha/build-raspberrypi-rdk-ipmc/tmp/deploy/images/raspberrypi-rdk-ipmc

dsrava434@dvm-yocto3-docker-dsrava434:~/varsha/build-raspberrypi-rdk-ipmc/tmp/deploy/images/raspberrypi-rdk-ipmc$ ls -lrt rdk-generic-ip-stb-client_rdk-next_20210913112356.rootfs.wic.bz2

-rw-r--r-- 2 dsrava434 dsrava434 141959535 Sep 13 12:33 rdk-generic-ip-stb-client_rdk-next_20210913112356.rootfs.wic.bz2

dsrava434@dvm-yocto3-docker-dsrava434:~/varsha/build-raspberrypi-rdk-ipmc/tmp/deploy/images/raspberrypi-rdk-ipmc$ 

# Insert the micro SD card to the host system and mention the card's device file name
# input file (if) is the image file to flash and the output file (of) is the card's device file name
bzcat <image name> | sudo dd of=/dev/<sd file> bs=4M iflag=fullblock oflag=direct conv=fsync

System View


Testing Procedure

  •  For connecting Controller UI, use URL: http://<machineip>:9998

  • Pluggins can be enabled or disabled from controller UI. 

  • Wifi related services can be triggered from Wi-Fi tab in controller UI. We can scan and select from available networks.

  • For ssh, we can use ssh root@machineip
  • For verifying the image details, we can use cat /version.txt command.    

root@raspberrypi-rdk-ipmc:~# cat /version.txt 

imagename:rdk-generic-ip-stb-client_rdk-next_20210902101930

BRANCH=rdk-next

YOCTO_VERSION=dunfell

VERSION=4.09.02.21

SPIN=0

BUILD_TIME="2021-09-02 10:19:30"

Generated on Thu Sep 02  10:19:30 UTC 2021

root@raspberrypi-rdk-ipmc:~# 

  • For playing a video using aamp-cli, launch aamp-cli from terminal, cd /usr/bin;aamp-cli.

  •  For playing a video using gstreamer, use gst-launch-1.0.

  eg :- gst-launch-1.0 playbin uri=aamp://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8 video-sink=westerossink

Known Issues

S. No

Issues

Status

Remarks

S. No

Issues

Status

Remarks

1Unable to pair bluetooth remote via resident appopenBT via controller UI is working as expected
2Wifi connections are unsuccessful via resident appOpenWifi via controller Ui is working as expected
3Playback using aamp-cli is not working as expectedopenplayback is successful, but screen is visible only if we disable residentapp service.
4Board reboot every 30 minutesopen

As work around, comment out On failure from dsmgr.service.

Path : /lib/systemd/system/dsmgr.service

Comment out " OnFailure=reboot-notifier@%i.service"

Jira Ticket: REFPLTV-1099 - Rebooting observed in RPi3 device in IPSTB image IN PROGRESS

5CNN application taking to more time to load the application.Sometimes device rebooted when we try to play any content.OpenSimilar behavior is observed in dunfell branch
6Vimeo application taking to more time to load the application.Sometimes device rebooted when we try to play any content. OpenSimilar behavior is observed in dunfell branch

Trouble Shooting

  •        If the wireless networks are not listed in controller wifi page, try after disabling and enabling wifi from Network page, networks will be listed.
  •        Disable cntlm-main.service if device reboot occasionally.


  • No labels