Porting Guide

From Tizen Wiki
Jump to: navigation, search

Contents

Introduction

About Tizen

Tizen is a standards-based platform that provides Web and native APIs for developing applications for multiple device categories. Tizen is currently targeted for smart phones and tablet devices, though planned to cover more device types in the future.

Purpose of this document

The intent of this document is to provide information and instruction to boot Tizen on new hardware and create products based on the Tizen OS. The Tizen porting guide takes you through the porting process by elaborating the Tizen architecture, the tools needed, the development environment setup, as well as creating a Tizen Image and demonstrating the modifications needed across various functional areas.

Tizen Architecture

The below figure illustrates the Tizen architecture for smartphone and tablet devices.

what_is_tizen_architecture.png

You can get detailed information of the Tizen framework layer from Dev Guide[1]

The Core Layer

Tizen Core Services

Application Framework

The Application Framework provides application management, including launching other applications using the package name, URI, or MIME type. It also launches pre-defined services, such as the system dialer application. The Application Framework also notifies applications of common events, such as low memory events, low battery, changes in screen orientation, and push notification.

Base

Base contains GNU/Linux * base essential system libraries that provide key features, such as database support, internationalization, and XML parsing.

Connectivity

Connectivity consists of all network- and connectivity-related functionalities, such as 3G, Wi-Fi, Bluetooth, HTTP, and NFC (Near Field Communication). Data network is based on ConnMan (Connection manager), which provides 3G and Wi-Fi based network connection management.

Graphics and UI

Graphics and UI consist of the system graphic and UI stacks, which includes EFL (Enlightenment Foundation Libraries), window management system (x11 for tizen 2.x / wayland for tizen 3.0), input methods, and OpenGL® ES APIs.

EFL, the heart of the Graphics component, is a suite of libraries. EFL is used to create rich graphics with ease, for all UI resolutions. The libraries build UIs in layers, allowing for 3D transformations and more. EFL includes the Evas canvas API library and the elementary widget library.

WebKit-based graphics is provided as well capable of running within a full browser UI or dedicated Web Runtime (without browser window), all based on Tizen's own HTML5 canvas WebKitEFL implementation. WebGL is supported too and Web-based frameworks for UI such as jQuery Mobile are also offered, what may help with porting existing jQuery code.

Location

Location provides location based services (LBS), including position information, geocoding, satellite information, and GPS status. It delivers location information from various positioning sources, such as GPS, WPS (Wi-Fi Positioning System), Cell ID, and sensors.

Messaging

Messaging consists of Message and Email. The Message supports SMS, MMS, and cell broadcast messages and the Email supports the protocols such as SMTP, IMAP, and POP3.

Multimedia

Multimedia is based on GStreamer. It provides support for media, including video, audio, imaging, and VoIP. It also provides media content management for managing media file metadata information.

PIM (Personal Information Management)

PIM enables managing user data on the device, including managing calendar, contacts, tasks, and retrieving data about the device context (such as device position and cable status).

Security

Security is responsible for security deployment across the system. It consists of platform security enablers, such as access control, certificate management, and secure application distribution.

For more information, refer to below link:

System

System consists of service(process) and device and resource management features, including:

  • Interfaces for accessing devices, such as sensors, display, or vibrator.
  • Power management, such as LCD display backlight dimming/off and application processor sleep.
  • Monitoring devices and handling events, such as USB, MMC, charger, and ear jack events.
  • Resource management, such as CPU quota control, low memory management.
  • Service management like watchdog management, capability control

Telephony

Telephony consists of cellular functionalities communicating with the modem:

  • Provides call services.(single call / multiparty call)
  • Provides call-related and non-call-related supplementary services.(Call Waiting/Barring/Forwarding and USSD)
  • Supports GSM, UMTS, LTE and CDMA network services.
  • Provides packet services and network status information.
  • Provides SMS-related services.
  • Provides SIM Card functionalities (SIM phonebook, SIM EF files, SIM Application Toolkit support)

Web

Web provides a complete implementation of the Tizen Web API optimized for low power devices. It includes WebKit, which is a layout engine designed to allow web browsers to render web pages. It also provides web runtimes for web applications.

Development Environment Setup

Please refer to the following links to set up the Tizen OS Development environment and to obtain information regarding development:

Getting Source Code&Build

Follow this to download the full source code for your Tizen platform and kernel.

  • 'git clone'
Download xml and extract each <git_path>
Clone each git project. git clone ssh://<Username>@review.tizen.org:29418/<git_path>

Example

$ wget https://download.tizen.org/releases/weekly/tizen/mobile/tizen-mobile_20160727.5/builddata/manifest/tizen-mobile_20160727.5_arm-wayland.xml
$ for i in `cat tizen-mobile_20160727.5_arm-wayland.xml | grep "path" |  awk -F "\"" '{print $4}'`; do mkdir -p $i; cd $i/..; git clone ssh://<Username>@review.tizen.org:29418/$i; cd -; done
  • 'repo init' and 'repo sync'
repo init -u ssh://<Username>@review.tizen.org:29418/scm/manifest -b <branch_name> -m <profile>.xml
Replace projects.xml file inside $workspace/.repo/ to manifest file in $srcrpm_snapshot
repo sync

Example

$ repo init -u ssh://<Username>@review.tizen.org:29418/scm/manifest -b tizen -m mobile.xml 
$ wget --directory-prefix=$workspace/.repo/manifests/mobile/ https://download.tizen.org/releases/weekly/tizen/mobile/tizen-mobile_20160727.5/builddata/manifest/tizen-mobile_20160727.5_arm-wayland.xml
$ mv $workspace/.repo/manifests/mobile/tizen-mobile_20160727.5_arm-wayland.xml projects.xml
$ repo sync

When there is en error in 'repo sync', check first of all whether git project name inside projects.xml exists in review.tizen.org or not.

Reference : Cloning tizen source

Refer to below link for more information

  • Source code Management on Tizen releases:
GIT/Gerrit: https://review.tizen.org/gerrit
  • Tizen Build setup
OBS: https://build.tizen.org/
  • Tizen Bug Tracking system
Jira: https://bugs.tizen.org/jira

Platform Build

  • Follow the link below to get learn how to add something to Tizen:

https://source.tizen.org/documentation/developer-guide

  • Follow the link below to build the source code by using git build system.

https://source.tizen.org/documentation/reference/git-build-system

  • Follow the link below to create the image by using mic

https://source.tizen.org/documentation/reference/mic-image-creator

Kernel Build

Follow below steps to build the Tizen kernel for the TM1 board.

  1. Install and setup cross compile tools on your system if the target and your host are different (e.g., x86).
  2. You may use Linaro toolchain binaries or Ubuntu package of them and have your environment setup for the cross tools (e.g., export CROSS_COMPILE=....)
  3. Prepare kernel source code for TM1 from profile/mobile/platform/kernel/linux-3.10-sc7730
    git: https://review.tizen.org/git/?p=profile/mobile/platform/kernel/linux-3.10-sc7730.git
    branch: accepted/tizen_mobile
  4. If your kernel source has been used to create binaries for other architecture, please start with cleaning them up.
    $ make distclean
  5. Setup the .config file for TM1
    $ make ARCH=arm tizen_tm1_defconfig
  6. Then, after reconfiguring per your needs (e.g., make ARCH=arm menuconfig) or using the stock configuration (no modifications), build it.
    $ make ARCH=arm zImage
    $ make ARCH=arm dtbs
  7. Then, create devicetree and zImage merged image with image tools
    $ scripts/sprd_dtbtool.sh -o arch/arm/boot/merged-dtb -p scripts/dtc/ -v arch/arm/boot/dts/
    $ scripts/sprd_mkdzimage.sh -o arch/arm/boot/dzImage -k arch/arm/boot/zImage -d arch/arm/boot/merged-dtb
  8. Build and make kernel module image as well. Note that you may need to do sudo first to let sudo -n work in the script
    $ sudo ls
    $ scripts/mkmodimg.sh
  9. make tar archive from dzImage and modules.img
  10. you may make your own tar file from the two files
    $ tar cf FILENAME_YOU_WANT.tar -C arch/arm/boot dzImage -C ../../../usr/tmp-mod modules.img
  11. Send the tar image to the target via lthor
    $ lthor FILENAME_YOU_WANT.tar

Image Build

So to what I've understood the entry sources are there :

https://review.tizen.org/gerrit/gitweb?p=profile/$profile/meta-$profile.git;a=tree
ex: https://review.tizen.org/git/?p=profile/mobile/meta-mobile.git;a=tree;h=refs/heads/tizen;hb=refs/heads/tizen

and then there is a compilation job is done inside obs by building this profile's image-configurations package,

ie:

https://review.tizen.org/git/?p=platform/upstream/image-configurations.git;a=shortlog;h=refs/heads/tizen

I suppose you thought about building the ks on your host but this is done in the chrooted env...

It could also build on your host using gbs So no need to install/rebuild kickstarter for your env i am not even sure it is actually supported (when I tried the program did not output anything ...)

Just pick the .ks in the resulted rpm files then you can use mic on your host

Tizen Bootup Overview

This section provides a brief overview of the typical booting sequence, starting from boot loader to the kernel and the platform.

Boot-1.png

Kernel Bootup

The Tizen bootup process is the same as any other Linux kernel. We just need to make sure that the correct machine ID and the boot arguments are passed from the boot loader.

Platform Bootup

After we have mounted the initial RAM disk image, initramfs hands over the control to systemd as system manager daemon in Tizen platform. From this point, systemd is responsible for probing all remaining hardware, mounting all necessary file systems and spawning all configured services. Basically system boot-up process is split up in various discrete steps. To synchronize point during start-up, Target units (some file whose name ends in '.target') are used for grouping units. The boot-up process is highly parallelized in each target so that the order in which specific target units are reached is not deterministic. The system-plugin-slp is an OAL plugin for configuration setting such as mount point (i.e. '/etc/fstab').


Below figure shows you early boot sequence after starting kernel

Boot-2.png

  • sysinit.target
    • Special Target unit for early boot-up scripts.
    • It has dependencies on necessary services and targets such as local-fs.target.
    • At this point, most of file systems like '/opt', '/tmp' and '/media' are mounted and systemd related daemons such as 'systemd-journald' are launched.


  • basic.target
    • Special Target unit for basic boot-up.
    • At this point, all necessary initialization for general purpose daemons such as mount points, sockets, timers and path units are completed.
    • Tizen specific services (e.g. vconf-setup, tizen-debug-level etc.) also are executed.


  • bootmode.target
    • Special Target unit to select boot mode.
    • If kernel boot parameter (i.e. /proc/cmdline) has 'charger_detect_boot' option that is passed by boot loader such as uboot, the platform boots up as charging mode. In this mode, system enters the low power mode and charges the battery.
    • If 'charger_detect_boot' option is not in kernel boot parameter, normal boot is started.


Below figure shows you the overview of normal booting sequence in Tizen platform.

Boot-3.png

  • multi-user.target
    • Special Target unit for setting up a multi-user system which is non-graphical support.
    • In Tizen platform, this target is used for launching platform infrastructure daemons such as dbus (system session), power manager, gps manager, telephony daemon, WRT (Web Run Time) security daemon and media server.
    • Some systemd-related daemons (e.g. systemd-logind) are also started in this phase.


  • graphical.target
    • Special Target unit for setting up a graphical environment.
    • Some important daemons (i.e. Access control server, OMA DS agent server etc) that should have root permission are launched at this point.
    • Tizen platform use systemd user session for App privilege daemons.
    • Some daemons related with graphic system such as Enlightenment (Windows manager) are launched as App privilege in this phase.
    • Tizen platform has its special target for middleware & mobile service: tizen-middleware.target starts platform service daemons such as calendar, contacts, email, message, sound, download provider etc. tizen-mobile-session.target starts some service daemons related with mobile session.

BSP Customization

This section covers the basic configuration, set up, and build procedure required for building the boot loader and the kernel image for ARM.


Bootloader Fundamentals

Boot loader is a small piece of software that is required to perform the basic hardware and peripheral initialization and load the kernel and proper devicetree binary for the device to RAM. For the Tizen platform, the boot loader comes in two parts. The first part is the primary boot loader and the second part is the secondary boot loader. The primary boot loader is the proprietary boot loader. The secondary boot loader is the open source boot loader u-boot, which is customized further for the Tizen platform.

If your platform is already loaded with the compatible boot loader software, then you can skip this section and move directly to the kernel section.

Bootloader Setup and Build

Follow the steps to build the Tizen TM1 bootloader

  1. Install and setup cross compile tools on your system if the target and your host are different (e.g., x86).
  2. You may use Linaro toolchain binaries or Ubuntu package of them and have your environment setup for the cross tools (e.g., export CROSS_COMPILE=....)
  3. Start with cleaning u-boot-tm1 source up. (Download source from u-boot-tm1 repository.)
    $ make distclean
  4. Setup the configration for TM1
    $ make ARCH=arm tizen_tm1_defconfig
  5. Build u-boot
    $ make ARCH=arm
  6. Once the build is successful, u-boot.bin file is created. (This step is for preventing from flashing the other "u-boot.bin")
    $ tools/mkimage_signed.sh u-boot.bin "tizen_tm1"
  7. After run the script, u-boot-mmc.bin file is created.
  8. Create a bootloader tarball to download u-boot binary onto the target
    $ tar cvf bootloader.tar u-boot-mmc.bin

Please be careful when you modify the bootloader because there is a risk of making the device a dead brick.

Bootloader Kernel Parameters

The command line parameters can be passed from boot loader to Linux kernel. Here are some example command line parameters.

   Example:
   console=ttyS1,115200n8
   mem=1024M
   loglevel=1

Kernel Fundamentals

The kernel is the operating system that drives the platform. Here the kernel refers to the open source Linux kernel that is customized for the Tizen platform. The following section will give a brief overview about the Tizen kernel setup, configuration, and the build procedure for building a Linux kernel for your Tizen platform. The output of the kernel binary will be a uImage that is suitable only for u-boot boot loader. If you have chosen for a secure booting configuration in your boot loader, then this uImage should be compatible with your boot loader.


Kernel Configurations

To download the Tizen kernel source package, refer to “Getting Source code and Build” section in this document. Set up or modify your kernel configuration, use the appropriate defconfig file from arch/arm/configs/ ( ARM CPU ).

For more detailed information about Tizen kernel configuration and kernel building, refer to the section “Kernel Build” under “Getting Source code and Build” in this document.

   Note: Tizen uses INOTIFY and does not use DNOTIFY. So, you should disable DNOTIFY from your kernel configuration.

If you want to use initramfs, you can use these configurations:

   CONFIG_INITRAMFS_SOURCE
   CONFIG_INITRAMFS_ROOT_UID
   CONFIG_INITRAMFS_ROOT_GID
   CONFIG_INITRAMFS_COMPRESSION_NONE/GZIP/BZIP2/LZNA/LZO


Tizen File System

Virtual Filesystem (VFS )

The virtual file system (VFS) is an abstraction layer on top of a more concrete file system (ext2, jfs, ext4, etc...). The VFS provides a switching layer between the SCI (System call interface) and the file systems supported by the kernel, as shown in below:

Filesystem.png

At the top of the VFS is a common API abstraction of functions, such as open, close, read, and writes. At the bottom of the VFS are the file system abstractions that define how the upper-layer functions are implemented with respect to specific file system.

Below the file system layer is the page cache, which provides a common set of functions to the file system layer (independent of any particular file system). This caching layer optimizes access to the physical devices by keeping data around for a short time (or speculatively read ahead, so that the data is available when needed). Below the page cache are the device drivers, which implement the interface for the particular physical device.


Tizen Partition Layout

The following description is an example of the Tizen partition layout. The product vendor can modify the sequence or partition layout for their devices, as needed.

Partitionlayout.png

The ‘boot’ partition is mounted in ‘/boot’ of rootfs. Here s-boot, u-boot, and kernel image are saved as a file format, provided as system.tar.

  1. CSA (Configuration Saved Area) is for non-volatile data that is calibration value of modem, etc.
  2. The boot partition includes kernel image, boot-loader image, and modem image. Additionally, it can have device driver modules.
  3. Third partition is reserved for the future.
  4. The ‘platform’ partition is mounted on the root directory ( / ). It contains fundamental frameworks for Tizen and some general utility for Linux. It may be provided as platform.img file.
  5. The ‘data’ partition is mounted on ‘/opt’ and it includes applications, libraries of applications, and the platform database. It may be provided as a data.img file.
  6. CSC (Customer Software Configuration) ‘csc’ partition is mounted on '/mnt/csc'. It can store the customer’s software configuration, such as default language, time zone, etc.
  7. UMS (USB Mass Storage) partition is mounted on ‘/opt/media’ and it includes default (media) contents. It may be provided as ums.img.
  8. Each image file, ‘platform.img’, ‘data.img’, and ‘ums.img’ can be zipped for downloading, like IMAGE_NAME.tar.gz.

File-system Hierarchy Standard in Tizen

Each partition has this hierarchy:

Filesystemhierarchy.png

Supported filesystems in Tizen

Filesystems that Tizen supports Extended 4 (Ext 4) file-system. The Tizen kernel has to be compiled to enable support for the other file systems like JFS, XFS, BTRFS, and Reiserfs.

Default File-system in Tizen

The Extended (Ext 4) file-system is configured as a default file-system for Tizen.


Configuration

The ext4 kernel configuration is done like this standard kernel configuration.


Reference

   CONFIG_EXT4_FS=y
   CONFIG_EXT4_FS_XATTR=y
   CONFIG_EXT4_USE_FOR_EXT23=y
   CONFIG_EXT4_FS_SECURITY=y 

These are the configuration option to enable in kernel configuration file. 

MMC/SD/SDIO

Description

Tizen supports MultiMediaCard, Secure Digital, and Secure Digital I/O Support. The MMC driver is implemented on top of host controller (such as SDHCI controller driver) and supports MMC, SD, SD High Speed, and SDHC cards.

If MMC is your booting device, read-write APIs, partition management, and flashing should be provided at the boot loader.

Mmc.png

MSHCI/SDHCI Features Overview

The MMC/SD/SDIO driver supports these features:

  • The driver is built in-kernel
  • MMC cards, including high speed cards
  • SD cards, including SD high speed and SDHC cards

MMC subsystem code structure in kernel is at /driver/mmc

MMC subsystem structure is divided into three parts:

MMC block device driver /driver/mmc/card/

Protocol stack for MMC, SD, SDIO /driver/mmc/core/

Host controller driver /driver/mmc/host/

Hotplug MMC event handling in Tizen

Based on the hotplug event handling, the notification is passed to the Deviced for device status changes. It detects, mounts, and monitors the status of the sd card.

Reference

SDHCI controller is supported MMC/SD/SDIO interface. And Mobile Storage Host controller is only supported the MMC interface.


Kernel Configuration for MMC Interface

   CONFIG_MMC_BLOCK
   CONFIG_MMC
   CONFIG_MSHCI (For Mobile Storage Interface enable)
   sys interface: /dev/mmcblk0pX


Kernel Configuration for SD/SDIO Interface

   CONFIG_MMC_BLOCK
   CONFIG_MMC
   CONFIG_MMC_SDHCI (For SDHCI host Interface enable)
   CONFIG_MMC_SDHCI_S3C (For Samsung SoC)
   sys interface: /dev/mmcblk1pX

Here ‘X’ denotes the MMC partition number. Details of partition mount point for Tizen are covered under Tizen partition Layout. v

System

systemd

Description

As system and service manager for Tizen system, systemd (ver. 43), is newly applied to platform, which is a replacement for the System V init daemon. Basically systemd provides a lot of functionality such as parallesized service execution, socket and D-Bus activation for starting services and daemon, on-demand starting of deamons, managing the service processes as a group using Linux cgroup, supporting automount points, snapshotting and restoring of services.


Below figure shows you the systemd architecture.

Systemd arch.PNG


systemd Utility

systemd provides developers with a lot of utilities for monitoring and contrling systemd itself and its services. For example, developers can query or send control commend to the systemd service manager using 'systemctl' utility. In order to see log message, developers can query the systemd journal using 'systemd-journalctl' utility.


systemd target

Tizen boot-up process is split up in various descrete steps and each step are grouped its unit using 'Target' unit to synchronize point. The boot-up process is highly parallelized in each target so that the order in which specific target units are reached in not deterministic.


systemd daemon

systemd daemon is a system and service manager for Tizen platform. When it runs as first process on boot, it acts as init system that brings up. If 'systemd' daemon is launched with '--user' option, it runs as user session. 'systemd-journald' is a system service that collects and stores log data from the Kernel, from user processes via syslog or STDOUT/STDERR.


systemd core

It is a systemd core part that manages all units such as service, socket, mount and so on, stores all log data. systemd core is controled by using systemd utility like 'systemctl'.


systemd library & Linux Kernel

systemd requires to enable 'cgroup' and 'autofs' option in Linux Kernel configuration. It also depends on dbus and some libraries such as libnotify, libudev and so on.

System Framework

Description

The System framework module abstracts low level system functions and manages the Tizen platform, in terms of platform policy, with the following major functionality.

Systemframework.png

The System framework contains these sub-components:

System server

The system server handles system events like out of memory, battery level, plug & play device status as well as handles process watchdog.

Power manager

The power manager is a session daemon that runs to manage the power for a system. It provides conditional state transition. The power manager transitions with any wakeup event, shifting to a higher power state. Similarly, based on timeouts, it transits to the next lower power state. The Tizen Power manager functionalities control display backlight dimming/off anddevice sleep.

Power manager conditional state transition

When an application such as a media player is running, there may be no input from the user for a long time, but the LCD should not be dimmed or turned off. Applications can request that the Power manager not change to a specific state.

Conditional state transition

Lock : keep system from entering lower state than specific state. For example, lock(LCD_OFF) forces system to be in LCD_NORMAL, LCD_DIM or LCD_OFF.

Unlock : allow system to enter lower state than specific state

Controlling the device’s power status and sleep mode.

   sys interface: /sys/power/state					
                  /sys/power/wakeup_count
                  /dev/event0					
                  /dev/event1

Device manager

  • Providing the interface to controlling all devices
  • LCD backlight dimming/off, application processor sleep
  • System monitoring and events handling from devices and system
  • Process/battery level/low memory monitoring
  • USB/MMC/charger/earjack event handling
  • Interfaces for accessing devices
  • LCD, touch, LED, vibrator, etc.

USB manager

  • Setting USB configurations to connect to the PC
  • Monitoring external USB host devices such as keyboards, mice, cameras, USB storages, and USB printers
  • Monitoring USB accessories which are compatible with the Android USB accessories

System OAL

The System OAL interface provides function pointers for OEMs to plug in their device/platform specific code to the System framework.

Porting OAL Interface

The OAL interface provides function pointers for OEMs to plugin their device/platform specific code to System framework.

OEM developers should implement API defined in devman_plugin_intf.h and compile their library as libslp_devman_plugin.so. OEM APIs can be grouped as power, battery, haptics, LED, light, and memory. Device Manager (devman) upon initialization calls const OEM_sys_devman_plugin_interface* OEM_sys_get_devman_plugin_interface() , which in turn returns the address of implemented OEM APIs.If and when applications request device manager APIs then appropriate OEM APIs referred by OEM_sys_devman_plugin_interface would be called.

Devman library uses sysfs for interfaces with device drivers and kernel. sysfs is a virtual file system provided by Linux 2.6 or above.

Configuration
Install the OEM library as libslp_devman_plugin.so to /usr/lib

OAL API definitions are in the devman_plugin_intf.h header file:

    typedef struct {
	int	(*OEM_sys_get_display_count) (int *value);

	int	(*OEM_sys_get_backlight_min_brightness) (int index, int *value);
	int	(*OEM_sys_get_backlight_max_brightness) (int index, int *value);
	int	(*OEM_sys_get_backlight_brightness) (int index, int *value, int power_saving);
	int	(*OEM_sys_set_backlight_brightness) (int index, int value, int power_saving);

	int	(*OEM_sys_set_backlight_dimming) (int index, int value);

	int	(*OEM_sys_get_backlight_acl_control) (int index, int *value);
	int	(*OEM_sys_set_backlight_acl_control) (int index, int value);

	int	(*OEM_sys_get_lcd_power) (int index, int *value);
	int	(*OEM_sys_set_lcd_power) (int index, int value);

	int	(*OEM_sys_get_image_enhance_mode) (int *value);
	int	(*OEM_sys_set_image_enhance_mode) (int value);
	int	(*OEM_sys_get_image_enhance_scenario) (int *value);
	int	(*OEM_sys_set_image_enhance_scenario) (int value);
	int	(*OEM_sys_get_image_enhance_tone) (int *value);
	int	(*OEM_sys_set_image_enhance_tone) (int value);
	int	(*OEM_sys_get_image_enhance_outdoor) (int *value);
	int	(*OEM_sys_set_image_enhance_outdoor) (int value);

	int	(*OEM_sys_get_image_enhance_tune) (int *value);
	int	(*OEM_sys_set_image_enhance_tune) (int value);

	int	(*OEM_sys_image_enhance_info) (int *value);

	int	(*OEM_sys_set_display_frame_rate) (int value);

	int	(*OEM_sys_get_uart_path) (int *value);
	int	(*OEM_sys_set_uart_path) (int value);

	int	(*OEM_sys_get_usb_path) (int *value);
	int	(*OEM_sys_set_usb_path) (int value);

	int	(*OEM_sys_get_haptic_vibetones_level_max) (int *value);
	int	(*OEM_sys_get_haptic_vibetones_level) (int *value);
	int	(*OEM_sys_set_haptic_vibetones_level) (int value);
	int	(*OEM_sys_set_haptic_vibetones_enable) (int value);
	int	(*OEM_sys_set_haptic_vibetones_oneshot) (int value);

	int	(*OEM_sys_get_battery_capacity) (int *value);
	int	(*OEM_sys_get_battery_capacity_raw) (int *value);
	int	(*OEM_sys_get_battery_charge_full) (int *value);
	int	(*OEM_sys_get_battery_charge_now) (int *value);
	int	(*OEM_sys_get_battery_present) (int *value);
	int	(*OEM_sys_get_battery_health) (int *value);
	int	(*OEM_sys_get_battery_polling_required) (int *value);

	int	(*OEM_sys_get_jack_charger_online) (int *value);
	int	(*OEM_sys_get_jack_earjack_online) (int *value);
	int	(*OEM_sys_get_jack_earkey_online) (int *value);
	int	(*OEM_sys_get_jack_hdmi_online) (int *value);
	int	(*OEM_sys_get_jack_usb_online) (int *value);
	int	(*OEM_sys_get_jack_cradle_online) (int *value);
	int	(*OEM_sys_get_jack_tvout_online) (int *value);
	int	(*OEM_sys_get_jack_keyboard_online) (int *value);

	int	(*OEM_sys_get_leds_torch_max_brightness) (int *value);
	int	(*OEM_sys_get_leds_torch_brightness) (int *value);
	int	(*OEM_sys_set_leds_torch_brightness) (int value);

	/* TODO: Change args type */
	int	(*OEM_sys_set_power_state) (int value);

	/* TODO: Should determine enum values of wakeup_count nodes */
	int	(*OEM_sys_get_power_wakeup_count) (int *value);
	int	(*OEM_sys_set_power_wakeup_count) (int value);

	int	(*OEM_sys_get_memnotify_node) (char *node);
	int	(*OEM_sys_get_memnotify_victim_task) (int *value);
	int	(*OEM_sys_set_memnotify_threshold_lv1) (int value);
	int	(*OEM_sys_set_memnotify_threshold_lv2) (int value);

	int	(*OEM_sys_get_process_monitor_node) (char *node);
	int	(*OEM_sys_set_process_monitor_mp_pnp) (int value);
	int	(*OEM_sys_set_process_monitor_mp_vip) (int value);

	int	(*OEM_sys_get_cpufreq_cpuinfo_max_freq) (int *value);
	int	(*OEM_sys_get_cpufreq_cpuinfo_min_freq) (int *value);
	int	(*OEM_sys_get_cpufreq_scaling_max_freq) (int *value);
	int	(*OEM_sys_set_cpufreq_scaling_max_freq) (int value);
	int	(*OEM_sys_get_cpufreq_scaling_min_freq) (int *value);
	int	(*OEM_sys_set_cpufreq_scaling_min_freq) (int value);} 
    OEM_sys_devman_plugin_interface;
    const OEM_sys_devman_plugin_interface *OEM_sys_get_devman_plugin_interface();

Device manager (devman) gets the pointer to the structure OEM_sys_get_devman_plugin_interface in variable plugin_intf, as shown below in the code.

    const OEM_sys_devman_plugin_interface *(*OEM_sys_get_devman_plugin_interface) ();
    
    OEM_sys_get_devman_plugin_interface = dlsym(dlopen_handle, "OEM_sys_get_devman_plugin_interface");
                if ((error = dlerror()) != NULL) {
                                ERR("dlsym() failed: %s", error);
                                dlclose(dlopen_handle);
                                return;
                }

                plugin_intf = OEM_sys_get_devman_plugin_interface();
               
     if (!plugin_intf) {
                                ERR("get_devman_plugin_interface() failed");
                                dlclose(dlopen_handle);
                                return;
                }

OAL API reference implementation:

   Sample implementation code for OEM_sys_get_backlight_brightness()

This function gets the current brightness of the backlight unit and the output is stored in the variable “value”. The “value” can range from  :0 <= value <= MAX_BACKLIGHT_BRIGHTNESS

The path for input and output parameters of OEM APIs can be found in file devman_define_node_path.h

    #define BATTERY_CAPACITY_PATH		"/sys/class/power_supply/battery/capacity"
    #define BATTERY_CHARGE_FULL_PATH	"/sys/class/power_supply/battery/charge_full"
    #define BACKLIGHT_PATH 		"/sys/class/backlight/"
    #define BACKLIGHT_MAX_BRIGHTNESS_PATH	BACKLIGHT_PATH"%s/max_brightness"
    #define BACKLIGHT_BRIGHTNESS_PATH 	BACKLIGHT_PATH"%s/brightness"

    int OEM_sys_get_backlight_brightness(int index, int *value, int power_saving)
    {
	int ret = -1;
	char path[MAX_NAME+1];
	int max_brightness;
	int pwr_saving_offset;

	if (index >= DISP_MAX) {
		devmgr_log("supports %d display node", DISP_MAX);
		return ret;
	}

	snprintf(path, MAX_NAME, BACKLIGHT_BRIGHTNESS_PATH, disp_info[index].bl_name);
	ret = sys_get_int(path, value);
	devmgr_log("path[%s]value[%d]power_saving[%d]", path, *value, power_saving);

	if (power_saving){
		snprintf(path, MAX_NAME, BACKLIGHT_MAX_BRIGHTNESS_PATH, disp_info[index].bl_name);
		ret = sys_get_int(path, &max_brightness);
		if (ret)
		{
			devmgr_log("Can't read max_brightness node[%s]", path);
			return ret;
		}
		pwr_saving_offset = (PWR_SAVING_CANDELA_CRITERION * max_brightness / MAX_CANDELA_CRITERION) + 0.5;

		if (*value > max_brightness - pwr_saving_offset)
			*value = max_brightness;
		else
			*value = *value + pwr_saving_offset;

		devmgr_log("power_saving result[%d]", *value);
	}

	return ret;
    }

The function, sys_get_int(path,value) provides access to kernel device driver node parameters. The parameter “path” is defined in the file devman_define_node_path.h , as described above. The value to be get/set is stored in parameter “value”. In similar ways , functions like sys_get_str, sys_set_int, sys_set_str, and sys_get_node are implemented to set/get the parameter values at the respective path. Here is the sample implementation for sys_get_int.

int sys_get_int(char *fname, int *val)
{
	char buf[BUFF_MAX];

	if (sys_read_buf(fname, buf) == 0) {
		*val = atoi(buf);
		return 0;
	} else {
		*val = -1;
		return -1;
	}
}
static int sys_read_buf(char *file, char *buf)
{
	int fd;
	int r;

	fd = open(file, O_RDONLY);
	if (fd == -1) {
		return -ENOENT;
	}

	r = read(fd, buf, BUFF_MAX);
	if ((r >= 0) && (r < BUFF_MAX))
		buf[r] = '\0';
	else {
		return -EIO;
	}

	close(fd);

	return 0;
}

Power manager

The various power states include Normal, LCD_DIM, LCD_OFF, and SLEEP and the device can switch from one state to another, as shown in the above diagram. The values for different states

The power states are defined in the below enum.
typedef enum 
    {
       POWER_STATE_NORMAL,     /**< Normal state */
       POWER_STATE_SCREEN_DIM, /**< Screen dim state */
       POWER_STATE-SCREEN_OFF, /**< Screen off state */
    } power_state_e;
Function Prototype Description (0-success, others -failure)
int (*OEM_sys_set_power_state) (int value); The function sets the device to suspend mode (0: Suspend Mode). Mandatory
int (*OEM_sys_get_power_wakeup_count) (int *value); The function gets the current “wakeup_count”. Mandatory
int (*OEM_sys_set_power_wakeup_count) (int value); The function sets the “wakeup_count” with input value. Mandatory
int (*OEM_sys_get_cpufreq_cpuinfo_max_freq) (int *value); The function gets the limitation of max cpu frequency value : cpu frequency (KHz). Optional
int (*OEM_sys_get_cpufreq_cpuinfo_min_freq) (int *value); The function gets the limitation of min cpu frequency value : cpu frequency (KHz). Optional
int (*OEM_sys_get_cpufreq_scaling_max_freq) (int *value); The function gets the current max cpu frequency(CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ in KHz). Optional
int (*OEM_sys_set_cpufreq_scaling_max_freq) (int value); The function sets the current max cpu frequency (CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ in KHz). Optional
int (*OEM_sys_get_cpufreq_scaling_min_freq) (int *value); The function gets the current min cpu frequency (CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ in KHz). Optional
int (*OEM_sys_set_cpufreq_scaling_min_freq) (int value); The function sets the current min cpu frequency (CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ in KHz). Optional
int (*OEM_sys_get_uart_path) (int *value); The function gets the current path of uart node (0: CP, 1: AP). Optional
int (*OEM_sys_set_uart_path) (int value); The function sets the current path of uart node (0: CP, 1: AP). Optional
int (*OEM_sys_get_usb_path) (int *value); The function gets the current path of usb node (0: CP, 1: AP). Optional
int (*OEM_sys_set_usb_path) (int value); The function sets the current path of usb node (0: CP, 1: AP). Optional
int (*OEM_sys_get_jack_charger_online) (int *value); The function gets the charger online status (0: Offline, 1: Online). Mandatory
int (*OEM_sys_get_jack_earjack_online) (int *value); The function gets the earjack online status (0: Offline, 1: Online). Mandatory
int (*OEM_sys_get_jack_earkey_online) (int *value); The function gets the earkey online status (0: Offline, 1: Online). Mandatory
int (*OEM_sys_get_jack_hdmi_online) (int *value); The function gets the hdmi online status (0: Offline, 1: Online). Optional
int (*OEM_sys_get_jack_usb_online) (int *value); The function gets the usb online status (0: Offline, 1: Online). Optional
int (*OEM_sys_get_jack_cradle_online) (int *value); The function gets the cradle online status (0: Offline, 1: Online). Optional
int (*OEM_sys_get_jack_tvout_online) (int *value); The function gets the TV out online status (0: Offline, 1: Online). Optional
int(*OEM_sys_get_jack_keyboard_online) (int *value); The fuction gets the keyboard interface status. Optional

Vibrator

Vibrator interfaces are used to for accessing vibrator device. They provides functions to control and retrieve vibrator parameters.

Function Prototype Description (0: Success, Others: Failed)
int (*OEM_sys_get_haptic_vibetones_level_max) (int *value) The function gets the max vibration feedback intensity level. Optional
int (*OEM_sys_get_haptic_vibetones_level) (int *value) The function gets the current vibration feedback intensity level (0 <= value <= VIBETONES_LEVEL_MAX). Optional
int (*OEM_sys_set_haptic_vibetones_level) (int value) The function sets the current vibration feedback intensity level (0 <= value <= VIBETONES_LEVEL_MAX). Optional
int (*OEM_sys_set_haptic_vibetones_enable) (int value) The function enables the vibration with current intensity level (0: Off, 1: On). Mandatory
int (*OEM_sys_set_haptic_vibetones_oneshot) (int value) The function enables the oneshot vibration with current intensity level (mili-second). Optional

Image Enhancement

Image Enhancement interfaces provides functions to control the Image Quality Enhancement Algorithm.

Function Prototype Description (0: Success, Others: Failed)
int (*OEM_sys_get_image_enhance_mode) (int *value); The function gets the mode of image enhance algorithm

(0 : DYNAMIC, 1 : STANDARD, 2 : NATURAL, 3 : MOVIE)

Optional
int (*OEM_sys_set_image_enhance_mode) (int value); The function sets the mode of image enhance algorithm

(0 : DYNAMIC, 1 : STANDARD, 2 : NATURAL, 3 : MOVIE)

Optional
int (*OEM_sys_get_image_enhance_scenario) (int *value); The function gets the scenario of image enhance algorithm

(0 : UI, 1 : GALLERY, 2: VIDEO, 3 : VTCALL, 4 : CAMERA, 5 : BROWSER, 6 : NEGATIVE, 7 : BYPASS)

Optional
int (*OEM_sys_set_image_enhance_scenario) (int value); The function sets the scenario of image enhance algorithm

(0 : UI, 1 : GALLERY, 2: VIDEO, 3 : VTCALL, 4 : CAMERA, 5 : BROWSER, 6 : NEGATIVE, 7 : BYPASS)

Optional
int (*OEM_sys_get_image_enhance_tone) (int *value); The function gets the tone of image enhance algorithm

(browser scenario - 0 : TONE_1, 1 : TONE_2, 2 : TONE_3) (other scenario - 0 : NORMAL, 1: WARM, 2: COLD)

Optional
int (*OEM_sys_set_image_enhance_tone) (int value); The function sets the tone of image enhance algorithm

(browser scenario - 0 : TONE_1, 1 : TONE_2, 2 : TONE_3) (other scenario - 0 : NORMAL, 1: WARM, 2: COLD)

Optional
int (*OEM_sys_get_image_enhance_outdoor) (int *value); The function gets the outdoor of image enhance algorithm

(0 : OUTDOOR_OFF, 1: OUTDOOR_ON)

Optional
int (*OEM_sys_set_image_enhance_outdoor) (int value); The function sets the outdoor of image enhance algorithm

(0 : OUTDOOR_OFF, 1: OUTDOOR_ON)

Optional
int (*OEM_sys_image_enhance_info) (int *value); This function reports whether Image Quality Enhancement Algorithm is supported Optional
int (*OEM_sys_set_display_frame_rate) (int value); The function sets the frame rate of LCD

(0 : OFF - 60HZ, 1 : ON - 40HZ)

Optional

Light

Light interfaces provides functions to control light, brightness, and get and set brightness of LED and to control power status of LCD power.

Function Prototype Description (0: Success, Others: Failed)
int (*OEM_sys_get_backlight_max_brightness) (int index, int *value) The function gets the max brightness of backlight unit. Mandatory
Int (*OEM_sys_get_backlight_min_brightness) (int index, int *value) The function gets the min brightness of backlight unit. Mandatory
int (*OEM_sys_get_backlight_brightness) (int index, int *value, int power_saving) The function gets the current brightness of backlight unit

(0 <= value <= MAX_BACKLIGHT_BRIGHTNESS).

Mandatory
int (*OEM_sys_set_backlight_brightness) (int index, int value, int power_saving) The function sets the current brightness of backlight unit

(0 <= value <= MAX_BACKLIGHT_BRIGHTNESS).

Mandatory
int (*OEM_sys_set_backlight_dimming) (int index, int value) The function sets the dimming status of backlight unit (0: Off, 1: On). Mandatory
int (*OEM_sys_get_backlight_acl_control) (int index, int *value) The function gets the current ACL control status of backlight unit (0: Off, 1: On). Optional
int (*OEM_sys_set_backlight_acl_control) (int index, int value) The function sets the current ACL control status of backlight unit (0: Off, 1: On). Optional
int (*OEM_sys_get_lcd_power) (int index, int *value) The function gets the current LCD power status (0: Off, 1: On). Optional
int (*OEM_sys_set_lcd_power) (int index, int value) The function sets the current LCD power status (0: Off, 1: On). Optional
int (*OEM_sys_get_leds_torch_max_brightness) (int *value) The function gets the max brightness of the led torch. Optional
int (*OEM_sys_get_leds_torch_brightness) (int *value) The function gets the current brightness of the led torch

(0 <= value <= TORCH_MAX_BRIGHTNESS).

Optional
int (*OEM_sys_set_leds_torch_brightness) (int value) The function sets the current brightness of the led torch

(0 <= value <= TORCH_MAX_BRIGHTNESS).

Optional

Keytouch OAL Interfaces

Key and touch event OAL interfaces uses standard input driver methods. These interfaces are used to get the key and touch events. The standard input structure in include/linux/input.h is:

struct input_event {
	struct timeval time;
	__u16 type;
	__u16 code;
	__s32 value;
};

Battery

Battery Interfaces provide access to battery status functions to retrieve current battery status information.

Function Name Description (0: Success, Others: Failed)
int (*OEM_sys_get_battery_capacity) (int *value) The function gets the current battery capacity (0 %< value < 100%). Mandatory
int (*OEM_sys_get_battery_capacity_raw) (int *value) The function gets the current battery capacity (0% < value < 10000%). Mandatory
int (*OEM_sys_get_battery_charge_full) (int *value) The function gets the current battery full charge status (0: Not full charge, 1: Full charge). Mandatory
int (*OEM_sys_get_battery_charge_now) (int *value) The function gets the battery charging status (0: Not charging, 1: Charging). Mandatory
int (*OEM_sys_get_battery_present) (int *value) The function gets the battery installation status (0: Not charging, 1: Charging). Mandatory
int (*OEM_sys_get_battery_health) (int *value) The function gets the temperature status

(0: UNKNOWN, 1: good, 2: overheat, 3: dead 4: overvoltage, 5: unspecified, 6: cold, 7: health max)

Optional

Utility

These utility OAL interfaces monitor process, notify low memory warning, and kill the process.

Function Name Description (0: Success, Others: Failed)
int (*OEM_sys_get_memnotify_node) (char *node); The function gets the node of out of memory notification. Mandatory
int (*OEM_sys_get_memnotify_victim_task) (int *value); The function gets the pid of victim process to be killed in OOM. Mandatory
int (*OEM_sys_set_memnotify_threshold_lv1) (int value); The function sets the memory size of thershold OOM level 1. Mandatory
int (*OEM_sys_set_memnotify_threshold_lv2) (int value); The function sets the memory size of thershold OOM level 2. Mandatory
int (*OEM_sys_get_process_monitor_node) (char *node); The function gets the node that send pid of unexpected killed proccess. Mandatory
int (*OEM_sys_set_process_monitor_mp_pnp) (int value); The function sets the pid of the process regarded as a permanent process. Mandatory
int (*OEM_sys_set_process_monitor_mp_vip) (int value); The function sets the pid of the process regarded as vip process type. Mandatory

Configuration

None

Reference

Packagename: device-manager-plugin-exynos

Include file : devman_define_node_path.h

Source file: device_manager_plugin_exynos.c

PM Kernel Configuration

Power management options
[*] Power Management support

Linux Suspend Resume Code is located at kernel/power

Generic Device/Bus suspend resume code located at drivers/base/power/

Device/Bus level suspend resume code in .suspend and .resume callbacks for each device driver or bus driver

sys interface: /sys/kernel/power/
CPU Idle

It is a generic framework for supporting software-controlled idle processor power management. It includes modular cross-platform governors that can be swapped during runtime.

[*] CPU idle PM support


The default CPU Idle governor is the menu governor and the code is located at drivers/cpuidle.

sys interface: /sys/devices/system/cpu/cpuidle/
CPU DVFS

It allows you to change the clock speed of CPUs on the fly. This is a nice method to save power, because the lower the CPU clock speed, the less power the CPU consumes.

[*] CPU Frequency scaling
[ ]   Enable CPUfreq debugging
<*>   CPU frequency translation statistics
[ ]     CPU frequency translation statistics details
-*-   Enable CPU tickling from drivers and users
      Default CPUfreq governor  (performance)  --->
-*-   'performance' governor
<*>   'powersave' governor
<*>   'userspace' governor for userspace frequency scaling
<*>   'ondemand' cpufreq policy governor
-*-     flexrate interface for 'ondemand' cpufreq policy governor
 (100)    flexrate's maximum duration of sampling rate override
<*>   'convervative' cpufreq governor

There are different generic CPU frequency governors, like performance, powersave, userspace, ondemand, etc., to control transitions among various Operating Points. The code is located at drivers/cpufreq.

sys interface: /sys/devices/system/cpu/cpufreq/


CPU Hotplug

In addition to the above, Tizen Power management provides extra features to support dynamic cpu hotplug to reduce power consumption.

To enable this feature, select this configuration:

-*- Support for hot-pluggable CPUs (EXPERIMENTAL)

sys interface: /sys/devices/system/cpu/

To support dynamic CPU hotplug to reduce power consumption, select this configuration System Type -> Support dynamic cpu hotplug ->

[*] Use Dynamic Hotplug
      Dynamic Hotplug Mechanism(PM Dynamic hotlug) --->
sys interface: /sys/module/pm_hotplug/


System OAL Kernel configuration
CONFIG_SLP_PROCESS_MON
CONFIG_INPUT
CONFIG_INPUT_MISC
CONFIG_INPUT_MOUSEDEV(Optional)
CONFIG_INPUT_KEYBOARD(Optional)
CONFIG_INPUT_TOUCHSCREEN(Optional)
CONFIG_FB
CONFIG_FB_S3C
CONFIG_BACKLIGHT_CLASS_DEVICE
CONFIG_LCD_CLASS_DEVICE
CONFIG_LCD_S6E8AA0
CONFIG_MMC
CONFIG_MMC_BLOCK
CONFIG_MMC_SDHCI_S3C
CONFIG_MMC_S3C_DEV_HSMMC*
CONFIG_USB_EXYNOS_SWITCH
CONFIG_UART_SELECT
CONFIG_VIBETONZ
CONFIG_CHARGER_MANAGER
CONFIG_PM
CONFIG_PM_SLEEP
CONFIG_JACKMON
CONFIG_CPU_FREQ
CONFIG_RTC_DRV_S3C
CONFIG_RTC_DRV_MAX8997

Sensor Framework

Description

Sensor devices are used widely in mobile devices to enhance user experience. Most modern mobile OSs have a framework which manages sensor hardware on the platform and provides convenient API to the application.

Types of Sensors

Tizen supports individual plugin frameworks for these sensors:

  • Accelerometer sensor
  • Gyroscope sensor
  • Proximity sensor
  • Motion sensor
  • Geomagnetic sensor
  • Light sensor

Note: Details are not available for Ambient light, Magnetic sensors

Sensorframework.png

Accelerometer sensor

The accelerometer sensor is used to measure the acceleration of the device. The three dimensional coordinate system is used to illustrate the direction of the acceleration. When a phone is moving along an axis, the acceleration is positive if it moves in a positive direction.

Gyroscope sensor

A gyroscope is a device used primarily for navigation and measurement of angular velocity. Gyroscopes measure how quickly an object rotates. This rate of rotation can be measured along any of the three axes X, Y, and Z.

Proximity sensor

A proximity sensor can detect the presence of nearby objects without any physical contact. That is, it indicates if the device is close or not close to the user.

Motion sensor

A motion sensor is a virtual sensor that uses the accelerometer and gyroscope sensors. Motion sensor detects snap, panning, tilt, shake, overturn, and double tap event.

Geomagnetic sensor

A geomagnetic sensor indicates the strength of the geomagnetic flux density in the X, Y, and Z axes. This sensor is used to find the orientation of a body, which is a description of how it is aligned to the space it is in.

Light sensor

A light sensor measures the amount of light that it receives or the surrounding light conditions. The ambient light state is measured as a step value, where 0 is very dark and 10 is bright sunlight.

Components of Sensor Framework

The Sensor framework provides a sensor server for creating plugins and a medium through which the client applications are connected to the sensor hardware to exchange data. The sensor plugins retrieve data from sensor hardware and enable the client applications to use the data for specific requirements.

Here's the description of the sensor framework components:

Sensor Library

The application that wants to access the sensor service should communicate with the daemon through the sensor API library. An API library allows the application to access the sensor service. As shown in the below diagram, applications/middleware frameworks can have the sensor-framework client library in the process context.

Sensor Server

The sensor server is a daemon which communicates uniquely to sensor drivers in the system and dispatches sensor data to the application. The sensor server takes care of interacting with the sensor driver in hardware initialization, driver configuration, and data fetching, to manage all sensors on the platform.

Type of plugins in sensor framework

Sensor Plugin

Sensor plugins takes care of interacting with the sensor driver. Plug-ins process data from sensor drivers and communicate it to the sensor server.

Processor
Active component (it has a thread) that processes data or makes events from a filter or from sensor data.
Filter
Passive component that converts sensor raw data to other types of data
Sensor
Passive component that gets raw data from the kernel node


Porting OAL Interface

The sensor OAL includes the processor plugin, the filter plugin, and the sensor plugin. The accelerometer sensor (accel) is taken as an example to illustrate each plugin prototype implementation. You can use common sensor plugin(processor, filter, sensor) code in git:sensor-framework/sensor-plugin-source

Processor Plugin

Active component (it has a thread) that processes data or makes events from a filter or from sensor data.

Prototype implementation of processor plugin
	
class accel_processor : public cprocessor_module {
 public:
	/*define enums*/
	/*define structures*/

	accel_processor();
	virtual ~ accel_processor();

	const char *name(void);
	int id(void);
	int version(void);

	bool update_name(char *name);
	bool update_id(int id);
	bool update_version(int version);
        bool add_input(csensor_module * sensor);
	bool add_input(cfilter_module * filter);

	long value(char *port);
	long value(int id);

	cprocessor_module *create_new(void);
	void destroy(cprocessor_module * module);

	static void *working(void *inst);
	static void *stopped(void *inst);

	virtual bool start(void);
	virtual bool stop(void);

	bool add_callback_func(cmd_reg_t * param);
	bool remove_callback_func(cmd_reg_t * param);
	bool check_callback_event(cmd_reg_t * param);

	long set_cmd(int type, int property, long input_value);
	int get_property(unsigned int property_level, void *property_data);
	int get_struct_value(unsigned int struct_type, void *struct_values);

	bool waiting_for_data(unsigned long time_us, bool real_update = false);

 private:
	/* Define private data structures and functions*/
};

Prototype Description Return Value
accel_processor() constructor, initialize all privite variables NA
virtual ~ accel_processor() destructor, deallocate variables NA
const char *name(void) return plugin's name return m_name (processor plugin name)
int id(void) return plugin's ID return m_id (processor plugin ID)
int version(void) return plugin's version return m_version (processor plugin version)
bool update_name(char *name) update sensor_name. param[in] char *name new processor plugin name Success- True

Failure-False

bool update_id(int id) update ID of plugin. param[in] int id new plugin ID Success- True

Failure-False

bool update_version(int version) update version of plugin. param[in] int version new plugin version Success- True

Failure-False

bool add_input(csensor_module * sensor) Add sensor module in processor plugin. param[in] csensor_module *sensor sensor plugin's module Success- True

Failure-False

bool add_input(cfilter_module * filter) Add filter module in processor plugin. param[in] cfilter_module *filter filter plugin's module Success- True

Failure-False

long value(int id) get sensor data by port id. param[in] desired port id return sensor data by port id
long value(char *port) get sensor data by port name. param[in] desired port name return sensor data by port name
cprocessor_module *create_new(void) create list of processors and return processor module Success- processor module instance
void destroy(cprocessor_module * module) delete module in list of processors and delete module Success- processor module instance
static void *working(void *inst) get sensor data and make event, set event to vconf. param[in] void *inst processor module NA
static void *stopped(void *inst) stop loop. param[in] void *inst processor module NA
virtual bool start(void) start processor plugin(set m_client for counting) Success- True

Failure-False

virtual bool stop(void) stop processor plugin(set m_client for counting) Success- True

Failure-False

bool add_callback_func(cmd_reg_t * param) register callback event. param[in] cmd_reg_t *param event parameter Success- True

Failure-False

bool remove_callback_func(cmd_reg_t * param) unregister callback event. param[in] cmd_reg_t *param event parameter Success- True

Failure-False

bool check_callback_event(cmd_reg_t * param) check callback event. param[in] cmd_reg_t *param event parameter Success- True

Failure-False

long set_cmd(int type, int property, long input_value) setting event or data in sensor and return result or output data. param[in] int type sensor type, int property property or command for sensor, input_value input data for property or command return output data from property or command
int get_property(unsigned int property_level, void *property_data) return sensor specification. param[in] unsigned int property_level desired specification

param[out] vod *property_data specification data

Success- 0

Failure – Negative value [-1]

int get_struct_value(unsigned int struct_type, void *struct_values) return menaingful sensor data. param[in] unsigned int struct_type desired data type

param[out] vod *struct_values meaningful data structure including values

Success- 0

Failure – Negative value [-1]

cmodule *module_init(void *win, void *egl) initial and create module. param[in] void *win, void *egl if it succeeds, it returns the created module, otherwise return NULL
void module_exit(cmodule *inst) delete created module. param[in] cmodlue *inst NA
	
EX) Accelerometer processor plugin code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
#include <pthread.h>
#include <string.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <math.h>
#include <sys/select.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <dirent.h>
#include <dlfcn.h>

#include <common.h>
#include <cobject_type.h>
#include <clist.h>
#include <cmutex.h>
#include <cmodule.h>
#include <csync.h>
#include <cworker.h>
#include <cpacket.h>
#include <csock.h>
#include <sf_common.h>

#include <csensor_module.h>
#include <cfilter_module.h>
#include <cprocessor_module.h>
#include <accel_processor.h>

#include <vconf.h>

#define ROTATION_0 0
#define ROTATION_90 90
#define ROTATION_180 180
#define ROTATION_270 270
#define ROTATION_360 360
#define ROTATION_THD 45
#define RADIAN_VALUE 57.29747
#define GRAVITY 9.80665
#define RAW_DATA_BY_MG_UNIT 1
#define G_TO_MG 1000
#define RAW_DATA_TO_G_UNIT ((float)RAW_DATA_BY_MG_UNIT/((float)1000))
#define RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT (GRAVITY * RAW_DATA_TO_G_UNIT)
#define LOW_FILTER_ALPHA 0.8
#define LOW_FILTER_ALPHA_R 0.2
#define MS_TO_US 1000

#define HORIZON_STRING_LENGTH 100
#define HORIZON_SEQ 30
#define SENSOR_NAME "accel_processor"
#define ROTATION_CB_KEY DEFAULT_SENSOR_KEY_PREFIX"10001"
#define HORIZON_CB_KEY DEFAULT_SENSOR_KEY_PREFIX"10008"
#define WAKEUP_CB_KEY DEFAULT_SENSOR_KEY_PREFIX"10010"


accel_processor::accel_processor()
: m_sensor(NULL)
, m_filter(NULL)
, m_x(-1)
, m_y(-1)
, m_z(-1)
, m_gravity_x(-1)
, m_gravity_y(-1)
, m_gravity_z(-1)
, m_curr_event(0)
, m_new_event(0)
, m_version(1)
, m_id(0x04BE)
, m_acc_theta(-1)
, m_acc_pitch(-1)
, m_client(0)
, m_work_err_count(0)
, m_rotation_cb_client(0)
, m_data_report_cb_client(0)
, m_set_horizon_cb_client(0)
, m_set_wakeup_cb_client(0)
, m_orientation_report_cb_client(0)
, m_linear_acceleration_report_cb_client(0)
, m_gravity_report_cb_client(0)
, m_fired_time(0)
, m_polling_interval_us(200000)
, m_curr_window_count(0)
, m_set_horizon_count(0)
, m_poll_counter(5)
, m_poll_max(POLL_5HZ)
{
	m_name = strdup(SENSOR_NAME);
	m_rotation_cb_key = strdup(ROTATION_CB_KEY);
	m_set_horizon_cb_key = strdup(HORIZON_CB_KEY);
	m_wakeup_cb_key = strdup(WAKEUP_CB_KEY);
	if ((!m_name) ||(!m_rotation_cb_key) || (!m_set_horizon_cb_key)) {
		free(m_name);
		m_name = NULL;
		free(m_rotation_cb_key);
		m_rotation_cb_key = NULL;
		free(m_set_horizon_cb_key);
		m_set_horizon_cb_key = NULL;
		free(m_wakeup_cb_key);
		m_wakeup_cb_key = NULL;
		throw ENOMEM;
	}

	rotation_mode[0].rotation = ROTATION_UNKNOWN;
	rotation_mode[0].rm[0] = ROTATION_UNKNOWN;
	rotation_mode[0].rm[1] = ROTATION_UNKNOWN;

	rotation_mode[1].rotation = ROTATION_HEAD_ROTATE_90;
	rotation_mode[1].rm[0] = ROTATION_LANDSCAPE_LEFT;
	rotation_mode[1].rm[1] = ROTATION_PORTRAIT_BTM;

	rotation_mode[2].rotation = ROTATION_HEAD_ROTATE_0;
	rotation_mode[2].rm[0] = ROTATION_PORTRAIT_TOP;
	rotation_mode[2].rm[1] = ROTATION_LANDSCAPE_LEFT;

	rotation_mode[3].rotation = ROTATION_HEAD_ROTATE_180;
	rotation_mode[3].rm[0] = ROTATION_PORTRAIT_BTM;
	rotation_mode[3].rm[1] = ROTATION_LANDSCAPE_RIGHT;

	rotation_mode[4].rotation = ROTATION_HEAD_ROTATE_270;
	rotation_mode[4].rm[0] = ROTATION_LANDSCAPE_RIGHT;
	rotation_mode[4].rm[1] = ROTATION_PORTRAIT_TOP;

	cprocessor_module::set_main(working, stopped, this);
}

accel_processor::~accel_processor()
{
	free(m_name);
	free(m_rotation_cb_key);
	free(m_set_horizon_cb_key);
	free(m_wakeup_cb_key);
}

bool accel_processor::add_input(csensor_module *sensor)
{
	m_sensor = sensor;
	return true;
}

bool accel_processor::add_input(cfilter_module *filter)
{
	m_filter = filter;
	return true;
}

const char *accel_processor::name(void)
{
	return m_name;
}

int accel_processor::id(void)
{
	return m_id;
}

int accel_processor::version(void)
{
	return m_version;
}

bool accel_processor::update_name(char *name)
{
	char *new_name;
	new_name = strdup(name);
	if (!new_name) {
		DbgPrint("No memory\n");
		return false;
	}

	free(m_name);
	m_name = new_name;
	return true;
}

bool accel_processor::update_id(int id)
{
	m_id = id;
	return true;
}

bool accel_processor::update_version(int version)
{
	m_version = version;
	return true;
}

cprocessor_module *accel_processor::create_new(void)
{
	return (cprocessor_module*)this;
}

void accel_processor::destroy(cprocessor_module *module)
{
	bool bstate = false;

	bstate = cmodule::del_from_list((cmodule *)module);

	if ( !bstate ) {
		ERR("Destory and del_from_list fail");
		delete (accel_processor *)module;	
		return ;
	}	
}

void *accel_processor::stopped(void *inst)
{

	accel_processor *processor = (accel_processor*)inst;

	if (!processor) {
		ERR("There is no processor module instance at accel (%s)\n", __FUNCTION__ );
	}

	return (void*)NULL;
}

void *accel_processor::working(void *inst)
{	
	long status_event = 0;	
	int state;

	csensor_module *sensor;
	long x, y, z;
	double norm_z, atan_value;
	int acc_theta , acc_pitch;
	int i;
	bool rotation_on = false;
        int smart_detection_state;

	accel_processor *processor = (accel_processor*)inst;
	if (!processor) {
		ERR("There is no processor module instance at accel (%s)\n", __FUNCTION__ );
		return (void*)cworker::STOPPED;
	}

	if (!processor->m_sensor ) {
		ERR("Sensor is not added\n");
		return (void*)cworker::STOPPED;
	}

	//! Implementation dependent
	sensor = (csensor_module*)processor->m_sensor;

	if (sensor->is_data_ready(true) == false) {

		processor->lock();
		processor->m_work_err_count++;
		if ( processor->m_work_err_count > 10 ) {
			processor->unlock();
			ERR("Too many error counted stop processor");
			return (void*)cworker::STOPPED;
		}
		processor->unlock();
		return (void*)cworker::STARTED;		
	}
		
	x =  sensor->value("x");
	y =  sensor->value("y");
	z =  sensor->value("z");

	processor->lock();

	if(processor->m_rotation_cb_client > 0)	{

		if(processor->m_poll_counter % processor->m_poll_max != 0)
		{
			processor->m_poll_counter += 5;
			processor->unlock();
			return (void*)cworker::STARTED;
		}
		else
			processor->m_poll_counter = 5;

		atan_value = atan2(x,y);
		acc_theta = (int)(atan_value * (RADIAN_VALUE) + 360)%360;

		if (z * RAW_DATA_TO_G_UNIT > 1.0) {
			norm_z = 1.0;
		} 
		else if (z * RAW_DATA_TO_G_UNIT < -1.0) {
			norm_z = -1.0;
		}
		else {
			norm_z = ((double)z * (double)RAW_DATA_TO_G_UNIT);
		}
		acc_pitch = (int)( acos(norm_z) *(RADIAN_VALUE));

		if( (acc_pitch>PITCH_MIN) && (acc_pitch<PITCH_MAX) ) {
			if ((acc_theta >= ROTATION_360 - ROTATION_THD && acc_theta <= ROTATION_360 - 1) || (acc_theta >= ROTATION_0 && acc_theta <= ROTATION_0 + ROTATION_THD))
			{
				status_event = processor->rotation_mode[ROTATION_HEAD_ROTATE_0].rm[processor->m_lcd_type];
			}
			else if(acc_theta >= ROTATION_90 - ROTATION_THD && acc_theta <= ROTATION_90 + ROTATION_THD)
			{
				status_event = processor->rotation_mode[ROTATION_HEAD_ROTATE_90].rm[processor->m_lcd_type];
			}
			else if(acc_theta >= ROTATION_180 - ROTATION_THD && acc_theta <= ROTATION_180 +	ROTATION_THD)
			{
				status_event = processor->rotation_mode[ROTATION_HEAD_ROTATE_180].rm[processor->m_lcd_type];
			}
			else if(acc_theta >= ROTATION_270 - ROTATION_THD && acc_theta <= ROTATION_270 +	ROTATION_THD)
			{
				status_event = processor->rotation_mode[ROTATION_HEAD_ROTATE_270].rm[processor->m_lcd_type];
			}		
		}

		processor->m_windowing[processor->m_curr_window_count++] = status_event;

		if (processor->m_curr_window_count == MAX_WINDOW_NUM )
			processor->m_curr_window_count = 0;

		for (i=0; i < MAX_WINDOW_NUM ; i++) {
			if( processor->m_windowing[i] == status_event)
				rotation_on = true;
			else
			{
				rotation_on = false;
				break;
			}
		}

		processor->m_acc_theta = acc_theta ;
		processor->m_acc_pitch = acc_pitch ;
		processor->m_curr_event = status_event;	

		if (processor->m_new_event != status_event && rotation_on && status_event != 0) {
			if ( processor->m_rotation_cb_client > 0 ) {
					DBG("get_smart_detection success");
					processor->m_new_event = status_event;
				}
				else
				{
					DBG("event changed , set new event at key : %s , value : %d \n", processor->m_rotation_cb_key , (int)(status_event));
					if ( processor->m_rotation_cb_key ) {
						state = vconf_set_int(processor->m_rotation_cb_key, (int)(status_event));
						if (state < 0 ) {
							ERR("Fail vconf_set_int at key : %s , value : %d\n",processor->m_rotation_cb_key, (int)(status_event));
						}
						else
							processor->m_new_event = status_event;
					}
				}
			}
		} else {
			DBG("No event changed\n");
		}
	}
	
	processor->m_x = x;
	processor->m_y = y;
	processor->m_z = z;

	//! TODO: How can I get the polling interval?
	//! TODO: When we get a polling interval, try read data in that interval :D
	processor->unlock();
	return (void*)cworker::STARTED;
}

long accel_processor::value(char *port)
{
	if (!strcasecmp(port, "acc_cod_x")) {
		return value(VALUE_ID_0);
	} else if (!strcasecmp(port, "acc_cod_y")) {
		return value(VALUE_ID_1);
	} else if (!strcasecmp(port, "acc_cod_z")) {
		return value(VALUE_ID_2);
	} else if (!strcasecmp(port, "acc_theta")) {
		return value(VALUE_ID_10);
	} else if (!strcasecmp(port, "acc_pitch")) {
		return value(VALUE_ID_11);
	} else if (!strcasecmp(port, "acc_state")) {
		return value(VALUE_ID_12);
	}	
	
	return -1;
}

long accel_processor::value(int id)
{
	if (id == VALUE_ID_0) {
		return m_x;
	} else if (id == VALUE_ID_1) {
		return m_y;
	} else if (id == VALUE_ID_2) {
		return m_z;
	} else if (id == VALUE_ID_10) {
		return m_acc_theta;
	} else if (id == VALUE_ID_11) {
		return m_acc_pitch;
	} else if (id == VALUE_ID_12) {
		return m_new_event;
	} 
	
	return -1;
}

bool accel_processor::start(void)
{
	bool ret;
	int i;

	cprocessor_module::lock();
	m_client ++;
	if (m_client > 1) {
		cprocessor_module::unlock();
		DBG("%s processor fake starting\n",m_name);
		return true;
	}

	DBG("%s processor real starting\n",m_name);

	for(i = 0 ; i < MAX_WINDOW_NUM ; i++)
		m_windowing[i] = 0;
	m_curr_window_count = 0;

	//! Before starting the processor module,
	//! We have to enable sensor
	ret = m_sensor ? m_sensor->start() : false;
	if ( ret != true ) {
		cprocessor_module::unlock();
		ERR("m_sensor start fail\n");
		return false;
	}

	cprocessor_module::start();
	cprocessor_module::unlock();
	return ret;
}

bool accel_processor::stop(void)
{
	bool ret;
	int i;

	cprocessor_module::lock();
	m_client --;
	if (m_client > 0) {
		cprocessor_module::unlock();
		DBG("%s processor fake Stopping\n",m_name);
		return true;
	}

	DBG("%s processor real Stopping\n",m_name);
	
	m_client = 0;

	for(i = 0 ; i < MAX_WINDOW_NUM ; i++)
		m_windowing[i] = 0;
	m_curr_window_count = 0;

	ret = cprocessor_module::stop();
	if ( ret != true ) {
		cprocessor_module::unlock();
		ERR("cprocessor_module::stop()\n");
		return false;
	}

	ret = m_sensor ? m_sensor->stop() : false;
	if ( ret != true ) {
		cprocessor_module::unlock();
		ERR("m_sensor stop fail\n");
		return false;
	}

	cprocessor_module::unlock();
	return ret;
}

bool accel_processor::add_callback_func(cmd_reg_t * param)
{
	char dummy_key[MAX_KEY_LEN];
	
	if ( param->type != REG_ADD ) {
		ERR("invaild cmd type !!");
		return false;
	}

	cprocessor_module::lock();
	switch ( param->event_type ) {
		case ACCELEROMETER_EVENT_ROTATION_CHECK:
			if ( (m_rotation_cb_client < 1) || ( !m_rotation_cb_key ) ) {
				memset(dummy_key,'\0',MAX_KEY_LEN);
				snprintf(dummy_key,(MAX_KEY_LEN-1),"%s%x",DEFAULT_SENSOR_KEY_PREFIX,param->event_type);
				if (m_rotation_cb_key) {
					free (m_rotation_cb_key);
					m_rotation_cb_key = NULL;
				}
				m_rotation_cb_key = strdup(dummy_key);
				if ( !m_rotation_cb_key ) {
					cprocessor_module::unlock();
					ERR("Err No memory for event key , evt_type : %x",param->event_type);
					return false;
				}
			}
			param->interval = 200;
			m_rotation_cb_client++;
			break;
		case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
			m_data_report_cb_client++;
			break;
		case ACCELEROMETER_EVENT_SET_HORIZON:
			m_set_horizon_cb_client++;
			break;
		case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
			m_orientation_report_cb_client++;
			break;
		case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME:
			m_linear_acceleration_report_cb_client++;
			break;
		case ACCELEROMETER_EVENT_SET_WAKEUP:
			set_cmd(ID_ACCEL, ACCELEROMETER_PROPERTY_SET_WAKEUP, 1);
		 	m_set_wakeup_cb_client++;
			break;
		case ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME:
			m_gravity_report_cb_client++;
			break;
		default:
			cprocessor_module::unlock();
			ERR("invaild event type !!");
			return false;
	}

	if(!cprocessor_module::add_interval_to_list(param->interval, m_polling_interval_us)){
		DBG("add_callback changed from interval = [%d] to [%d]",m_polling_interval_us / 1000, param->interval);
		m_polling_interval_us = cprocessor_module::norm_interval(param->interval) * MS_TO_US;
		m_poll_max = cprocessor_module::check_hz(param->interval);
		m_sensor->update_polling_interval(cprocessor_module::norm_interval(param->interval));
	}
	cprocessor_module::unlock();
	DBG("add_callback interval = [%d] param-interval = [%d]",m_polling_interval_us / 1000, param->interval);

	return true;
}

bool accel_processor::remove_callback_func(cmd_reg_t * param)
{
	int min_interval = 0;

	if ( param->type != REG_DEL ) {
		ERR("invaild cmd type !!");
		return false;
	}
	cprocessor_module::lock();
	switch ( param->event_type ) {
		case ACCELEROMETER_EVENT_ROTATION_CHECK:
			if ( m_rotation_cb_client == 0 ) {
				cprocessor_module::unlock();
				ERR("There is no registed client !!");
				return false;
			}
			if(m_rotation_cb_client > 0)
				m_rotation_cb_client--;
			if ( (m_rotation_cb_client == 0) && (m_rotation_cb_key!=NULL) ) {
				free (m_rotation_cb_key);
				m_rotation_cb_key = NULL;				
			}
			param->interval = 200;
			break;
		case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
			if(m_data_report_cb_client > 0)
				m_data_report_cb_client--;
			break;
		case ACCELEROMETER_EVENT_SET_HORIZON:
			if(m_set_horizon_cb_client > 0)
				m_set_horizon_cb_client--;
			break;
		case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
			if(m_orientation_report_cb_client > 0)
				m_orientation_report_cb_client--;
			break;
		case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME:
			if(m_linear_acceleration_report_cb_client > 0)
				m_linear_acceleration_report_cb_client--;
			break;
		case ACCELEROMETER_EVENT_SET_WAKEUP:
			if(m_set_wakeup_cb_client > 0)
			{
				set_cmd(ID_ACCEL, ACCELEROMETER_PROPERTY_SET_WAKEUP, 0);
				m_set_wakeup_cb_client--;
			}
			break;
		case ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME:
			if(m_gravity_report_cb_client > 0)
				m_gravity_report_cb_client--;
			break;
		default:
			cprocessor_module::unlock();
			ERR("invaild event type !!");
			return false;
	}	

	min_interval = cprocessor_module::del_interval_to_list(param->interval, m_polling_interval_us);

	DBG("del_callback before interval = [%d]",m_polling_interval_us / 1000);
	m_polling_interval_us = cprocessor_module::norm_interval(min_interval) * MS_TO_US;
	m_poll_max = check_hz(min_interval);
	m_sensor->update_polling_interval(cprocessor_module::norm_interval(min_interval));
	cprocessor_module::unlock();

	DBG("del_callback end interval = [%d]",cprocessor_module::norm_interval(min_interval));

	return true;
}

bool accel_processor::check_callback_event(cmd_reg_t *param)
{
	if ( param->type != REG_CHK ) {
		ERR("invaild cmd type !!");
		return false;
	}

	switch ( param->event_type ) {
		case ACCELEROMETER_EVENT_ROTATION_CHECK:
		case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
		case ACCELEROMETER_EVENT_SET_HORIZON:
		case ACCELEROMETER_EVENT_SET_WAKEUP:
		case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
		case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME:
		case ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME:
			 DBG("event check ok\n");
			break;
			
		default:
			ERR("invaild event type !!");
			return false;
	}	

	return true;
}

long accel_processor::set_cmd(int type , int property , long input_value)
{
	int ret = 0;

	ret = m_sensor ? m_sensor->set_cmd(type, property, input_value) : 0;
	if(ret < 0)
	{
		ERR("m_sensor set_cmd fail");
		return ret;
	}

	DBG("ret = [%d] property = [%d]",ret, property);
	return ret;
}

int accel_processor::get_property(unsigned int property_level , void *property_data )
{
	int result = -1;
	base_property_struct *return_property;
	return_property = (base_property_struct *)property_data;

	if (m_sensor) {
		result = m_sensor->get_property(ACCELEROMETER_BASE_DATA_SET , return_property);
		if(result == 0)
		{
			if(property_level == ACCELEROMETER_BASE_DATA_SET)
			{
				return result;
			}
			else if(property_level == ACCELEROMETER_ORIENTATION_DATA_SET)
			{
				return_property->sensor_unit_idx = IDX_UNIT_DEGREE;
				return_property->sensor_min_range = -180;
				return_property->sensor_max_range = 360;
				return_property->sensor_resolution = 1;
			}
			else if(property_level == ACCELEROMETER_LINEAR_ACCELERATION_DATA_SET)
			{
				return_property->sensor_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
				return_property->sensor_min_range = -20.0;
				return_property->sensor_max_range =  20.0;
				return_property->sensor_resolution = 0.1;
			}
			else if(property_level == ACCELEROMETER_GRAVITY_DATA_SET)
			{
				return_property->sensor_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
				return_property->sensor_min_range = -2.0;
				return_property->sensor_max_range =  2.0;
				return_property->sensor_resolution = 0.01;
			}
			else
			{
				ERR("cannot get_property from sensor\n");
				return -1;
			}
			return result;
		}
	} else {
			ERR("no m_sensor , cannot get_property from sensor\n");
	}
	return -1;
}

int accel_processor::get_struct_value(unsigned int struct_type , void *struct_values)
{
	int state;
	base_data_struct sensor_struct_data;
	base_data_struct *return_struct_data = NULL;

	state = m_sensor ? m_sensor->get_struct_value(ACCELEROMETER_BASE_DATA_SET , &sensor_struct_data) : -1;
	if (state<0) {
		ERR("Error , m_sensor get struct_data fail\n");
		return -1;
	}

	if ( struct_type == ACCELEROMETER_BASE_DATA_SET  ) {
		return_struct_data = (base_data_struct *)struct_values;
		return_struct_data->data_accuracy = sensor_struct_data.data_accuracy;
		return_struct_data->data_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
		return_struct_data->values_num = 3;
		return_struct_data->values[0] = sensor_struct_data.values[0] * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
		return_struct_data->values[1] = sensor_struct_data.values[1] * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
		return_struct_data->values[2] = sensor_struct_data.values[2] * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
	} else 	if ( struct_type == ACCELEROMETER_ORIENTATION_DATA_SET  ) {
		return_struct_data = (base_data_struct *)struct_values;
		return_struct_data->data_accuracy = sensor_struct_data.data_accuracy;
		return_struct_data->data_unit_idx = IDX_UNIT_DEGREE;
		return_struct_data->values_num = 3;
		return_struct_data->values[0] = (int)(atan2(sensor_struct_data.values[0], sensor_struct_data.values[1]) * RADIAN_VALUE + 360) % 360;
		return_struct_data->values[1] =	(int)(atan2(sensor_struct_data.values[1], sensor_struct_data.values[2]) * RADIAN_VALUE      ) % 180;
		return_struct_data->values[2] = (int)(atan2(sensor_struct_data.values[0], sensor_struct_data.values[2]) * RADIAN_VALUE      ) % 180;

		if(return_struct_data->values[2] > 90)
			return_struct_data->values[2] = 180 - return_struct_data->values[2];
		else if (return_struct_data->values[2] < -90)
			return_struct_data->values[2] = -180 - return_struct_data->values[2];
	} else if (struct_type == ACCELEROMETER_LINEAR_ACCELERATION_DATA_SET) {
		return_struct_data = (base_data_struct *)struct_values;
		return_struct_data->data_accuracy = sensor_struct_data.data_accuracy;
		return_struct_data->data_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
		return_struct_data->values_num = 3;
		cprocessor_module::lock();
		m_gravity_x = (LOW_FILTER_ALPHA * m_gravity_x) + (LOW_FILTER_ALPHA_R * sensor_struct_data.values[0]);
		m_gravity_y = (LOW_FILTER_ALPHA * m_gravity_y) + (LOW_FILTER_ALPHA_R * sensor_struct_data.values[1]);
		m_gravity_z = (LOW_FILTER_ALPHA * m_gravity_z) + (LOW_FILTER_ALPHA_R * sensor_struct_data.values[2]);
		return_struct_data->values[0] = (sensor_struct_data.values[0] - m_gravity_x) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
		return_struct_data->values[1] = (sensor_struct_data.values[1] - m_gravity_y) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
		return_struct_data->values[2] = (sensor_struct_data.values[2] - m_gravity_z) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT;
		cprocessor_module::unlock();
	} else if (struct_type == ACCELEROMETER_GRAVITY_DATA_SET) {
                return_struct_data = (base_data_struct *)struct_values;
                return_struct_data->data_accuracy = sensor_struct_data.data_accuracy;
                return_struct_data->data_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
                return_struct_data->values_num = 3;
                return_struct_data->values[0] = sensor_struct_data.values[0] * RAW_DATA_TO_G_UNIT;
                return_struct_data->values[1] = sensor_struct_data.values[1] * RAW_DATA_TO_G_UNIT;
                return_struct_data->values[2] = sensor_struct_data.values[2] * RAW_DATA_TO_G_UNIT;
	}else {
		ERR("does not support stuct_type\n");
		return -1;
	}

	return 0;

}

cmodule *module_init(void *win, void *egl)
{
	accel_processor *inst;

	try {
		inst = new accel_processor();
	} catch (int ErrNo) {
		ERR("accel_processor class create fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
		return NULL;
	}

	return (cmodule*)inst;
}



void module_exit(cmodule *inst)
{
	accel_processor *sample = (accel_processor*)inst;
	delete sample;
}
//! End of a file

Sensor Plugin

A passive component that gets raw data from the kernel node.

Prototype implementation sensor plugin
class caccel:public csensor_module {
 public:
/*define enums*/
	/*define structures*/

	caccel();
	virtual ~ caccel();
	const char *name(void);
	int version(void);
	int id(void);

	bool is_data_ready(bool wait = false);
	long value(const char *port);
	long value(int id);
	bool update_name(char *name);
	bool update_version(int ver);
	bool update_id(int id);
	int port_count(void);
	const char *port(int idx);
	bool need_polling(void);
	long polling_interval(void);
	bool update_polling_interval(unsigned long val);
	int get_sensor_type(void);
	long set_cmd(int type, int property, long input_value);
	int get_property(unsigned int property_level, void *property_data);
	int get_struct_value(unsigned int struct_type, void *struct_values);
	bool calibration(int iteration);
	int check_hw_node(void);
	bool start(void);
	bool stop(void);
	void reset(void);

 private:
/* Define private data structures and functions*/
};
Prototype Description
bool is_data_ready(bool wait) When sensor data is available that can be read from sensor node, then return that status. This function waits during polling time and calls update_value. If wait is true, then wait during polling interval time.
int port_count(void) Returns the port count in sensor. For example, accelerometer sensor has X, Y, Z port. In this case, port_count function return 3.
const char *port(int idx) Returns port name by index number. When port(0) called in the accelerometer sensor, then this function returns ‘x’.
void reset(void) Reset s sensor node.
bool start(void) / bool stop(void) This function enables or disables the sensor. It is the interface for the on or off function for the sensor. It starts or stops function success, then returns true. Otherwise, it returns false.
bool need_polling(void) This function announces that sensor’s data reading type is polling or interrupt. If it is true, it is polling, otherwise it is interrupt.
long polling_interval(void) It senses the need to poll data. Then returns the polling interval time by ms.
bool update_polling_interval(unsigned long val) Updates polling interval by ms.
void lock(void) Locks the sensor and blocks the other component’s access.
void unlock(void) Unlocks the sensor and releases the other component's access.
 EX) Sensor plugin code (lsm330dlc accelerometer sensor)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <dirent.h>
#include <sys/poll.h>

#include <common.h>
#include <cobject_type.h>
#include <cmutex.h>
#include <clist.h>
#include <cmodule.h>
#include <cpacket.h>
#include <csync.h>
#include <cworker.h>
#include <csock.h>
#include <sf_common.h>

#include <csensor_module.h>

#include <clsm330dlc_accel.h>
#include <sys/ioctl.h>

#define ACC_DEV_NODE "/dev/accelerometer"

/* lsm330dlc_accel_ACCEL ioctl command label */
#define LSM330DLC_ACCEL_IOCTL_BASE 'a'
#define LSM330DLC_ACCEL_IOCTL_SET_DELAY _IOW(LSM330DLC_ACCEL_IOCTL_BASE, 0, int64_t)
#define LSM330DLC_ACCEL_IOCTL_GET_DELAY _IOR(LSM330DLC_ACCEL_IOCTL_BASE, 1, int64_t)
#define LSM330DLC_ACCEL_IOCTL_READ_XYZ  _IOR(LSM330DLC_ACCEL_IOCTL_BASE, 8, struct lsm330dlc_acc)
#define LSM330DLC_ACCEL_IOCTL_SET_ENABLE _IOW(LSM330DLC_ACCEL_IOCTL_BASE, 9, int)

#define SENSOR_NAME "lsm330dlc_accel"
#define SENSOR_CHIP_NAME "LSM330DLC"
#define SENSOR_CHIP_VENDOR "ST Microelectronics"
#define WAKEUP_NODE "/sys/class/sensors/accelerometer_sensor/reactive_alert"
#define CALIBRATION_NODE "/sys/class/sensors/accelerometer_sensor/calibration"
#define CALIBRATION_FILE "/csa/sensor/accel_cal_data"
#define CALIBRATION_DIR  "/csa/sensor"

#define SENSOR_NODE_LENGTH 256
#define CHIP_NAME_LENGTH   50

#define REACTIVE_ALERT_OFF	0
#define REACTIVE_ALERT_ON	3

static const int64_t accel_delay_ns[] = {
	744047LL , /* 1344Hz */
	2500000LL , /*  400Hz */
	5000000LL , /*  200Hz */
	10000000LL , /*  100Hz */
	20000000LL , /*   50Hz */
	40000000LL , /*   25Hz */
	100000000LL , /*   10Hz */
	1000000000LL , /*    1Hz */
};


struct lsm330dlc_acc {
	int16_t x;
	int16_t y;
	int16_t z;
};

const char *clsm330dlc_accel::m_port[] = {"x", "y", "z",};

clsm330dlc_accel::clsm330dlc_accel()
: m_id(0x0000045A)
, m_version(1)
, m_polling_interval(100000)
, m_x(-1)
, m_y(-1)
, m_z(-1)
, m_fired_time(0)
, m_client(0)
, m_sensor_type(ID_ACCEL)
{
	m_name = strdup(SENSOR_NAME);
	m_wakeup_resource = strdup(WAKEUP_NODE);
	if ((!m_name) || (!m_wakeup_resource)) {
		free(m_name);
		free(m_wakeup_resource);
		throw ENOMEM;
	}

	if (check_hw_node() != 1 ) {
		free(m_name);
		free(m_wakeup_resource);
		throw ENXIO;
	}	
}

clsm330dlc_accel::~clsm330dlc_accel()
{
	free(m_name);
	free(m_wakeup_resource);
}

const char *clsm330dlc_accel::name(void)
{
	return m_name;
}

int clsm330dlc_accel::version(void)
{
	return m_version;
}

int clsm330dlc_accel::id(void)
{
	return m_version;
}

/*****************************************
  read sensor data from kernel
  can use i2c, ioctrl, fopen and fread
 ****************************************/
bool clsm330dlc_accel::update_value(void)
{
	int x;
	int y;
	int z;	
	struct lsm330dlc_acc acc_data;

	if(ioctl(accel_file_handle, LSM330DLC_ACCEL_IOCTL_READ_XYZ, &acc_data) < 0)
	{
		ERR("cannot read ioctl for lsm330dlc_accel\n");
		return false;
	}
	else
	{
		x = acc_data.x;
		y = acc_data.y;
		z = acc_data.z;
	}

	csensor_module::lock();	

	m_x = x;
	m_y = y;
	m_z = z;

	csensor_module::unlock();

	DBG("Update done raw : %d, %d, %d , out_data : %d, %d, %d\n", x,y,z,m_x, m_y, m_z);
	return true;
}

bool clsm330dlc_accel::is_data_ready(bool wait)
{
	bool ret = false;

	DBG("Sensor, invoked\n");

	if(wait)
	{
		unsigned long long cur_time;
		unsigned long elapsed_time;
		struct timeval sv;
		gettimeofday(&sv, NULL);
		cur_time = MICROSECONDS(sv);

		elapsed_time = (unsigned long)(cur_time - m_fired_time);

		if (elapsed_time < m_polling_interval) {
			usleep(m_polling_interval - elapsed_time);
			csensor_module::lock();
			m_fired_time = cur_time + (m_polling_interval-elapsed_time);
			csensor_module::unlock();
			ret = update_value();
		}
		else
			csensor_module::lock();
			m_fired_time = cur_time;
			csensor_module::unlock();
			return true;
	} else {
		DBG("update_value directly");
		ret = update_value();
	}


	return ret;
}

long clsm330dlc_accel::value(const char *port)
{

	if (!strcasecmp(port, "x")) {
		return m_x;
	} else if (!strcasecmp(port, "y")) {
		return m_y;
	} else if (!strcasecmp(port, "z")) {
		return m_z;
	}

	return -1;
}

long clsm330dlc_accel::value(int id)
{

	if (id == 0) {
		return m_x;
	} else if (id == 1) {
		return m_y;
	} else if (id == 2) {
		return m_z;
	}

	return -1;
}

void clsm330dlc_accel::reset(void)
{
	return;
}

bool clsm330dlc_accel::update_name(char *name)
{
	char *new_name;
	new_name = strdup(name);
	if (!new_name) {
		DBG("No memory\n");
		return false;
	}

	free(m_name);
	m_name = new_name;
	return true;
}

bool clsm330dlc_accel::update_version(int version)
{
	m_version = version;
	return true;
}

bool clsm330dlc_accel::update_id(int id)
{
	m_id = id;
	return true;
}

int clsm330dlc_accel::port_count(void)
{
	return 3;
}

const char *clsm330dlc_accel::port(int idx)
{
	if (idx >= (int)(sizeof(m_port)/sizeof(const char*))) {
		return NULL;
	}

	return m_port[idx];
}

bool clsm330dlc_accel::need_polling(void)
{
	return m_polling_interval != 0;
}

long clsm330dlc_accel::polling_interval(void)
{
	return (unsigned long long)m_polling_interval /1000llu ;
}

bool clsm330dlc_accel::update_polling_interval(unsigned long val)
{
	if(val < 1)
	{
		ERR("invaild interval value");
		return false;
	}

	DBG("Update polling interval %lu\n", val);
	int64_t curr_delay_ns = val * 1000000;
	csensor_module::lock();
	m_polling_interval = (unsigned long long)val * 1000llu;
	csensor_module::unlock();

	return true;
}

bool clsm330dlc_accel::start(void)
{
	int64_t curr_delay_ns = 10000000LL;
	int sensor_enable = 1;

	m_client ++;

	if (m_client > 1) {
		return true;
	}

	if((accel_file_handle = open(ACC_DEV_NODE, O_RDWR)) < 0)
	{
		ERR("lsm330dlc_accel Accel sensor node open fail\n");
		return false;
	}

	if(ioctl(accel_file_handle, LSM330DLC_ACCEL_IOCTL_SET_DELAY, &curr_delay_ns) < 0)
	{
		DBG("set delay fail");
		close(accel_file_handle);

		return false;
	}

	if(ioctl(accel_file_handle, LSM330DLC_ACCEL_IOCTL_SET_ENABLE, &sensor_enable) < 0)
	{
		DBG("enable sensor fail");
		close(accel_file_handle);

		return false;
	}

	return true;
}

bool clsm330dlc_accel::stop(void)
{

	int sensor_enable = 0;

	m_client --;
	if (m_client > 0) {
		DBG("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Stopping\n");
		return true;
	}

	if(ioctl(accel_file_handle, LSM330DLC_ACCEL_IOCTL_SET_ENABLE, &sensor_enable) < 0)
	{
		DBG("disable sensor fail");
		close(accel_file_handle);

		return false;
	}

	close(accel_file_handle);

	return true;
}

int clsm330dlc_accel::get_sensor_type(void)
{
	return m_sensor_type;
}

int clsm330dlc_accel::set_reactive_alert(int input)
{
	FILE *fp;

	fp = fopen(WAKEUP_NODE, "w");
	if (!fp){
		DBG("err WAKEUP_NODE initialize\n");
		return -1;
	}

	fprintf(fp, "%d",input);
	fclose(fp);

	return 0;
}

long clsm330dlc_accel::set_cmd(int type , int property , long input_value)
{
	long value = -1;
	struct pollfd Events;
	int retval;
	unsigned char buff = 0;
	FILE *fp;

	if ( type == m_sensor_type) {
		switch (property) {
			case ACCELEROMETER_PROPERTY_SET_CALIBRATION :				
			default :
				ERR("Invalid property_cmd\n");
				break;				
		}
	}
	else {
		ERR("Invalid sensor_type\n");		
	}

	return value;

}

/*************************************
  sensor property 
*************************************/
int clsm330dlc_accel::get_property(unsigned int property_level , void *property_data)
{
	if ( (property_level & 0xFFFF) == 1 ) {
		base_property_struct *return_property;
		return_property = (base_property_struct *)property_data;
		return_property->sensor_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
		return_property->sensor_min_range = -20.09088;
		return_property->sensor_max_range = 19.93392;
		snprintf(return_property->sensor_name,   sizeof(return_property->sensor_name),   SENSOR_CHIP_NAME  );
		snprintf(return_property->sensor_vendor, sizeof(return_property->sensor_vendor), SENSOR_CHIP_VENDOR);
		return_property->sensor_resolution = 0.15696;
		return 0;

	} else {
		ERR("Doesnot support property_level : %d\n",property_level);
		return -1;
	}

	return -1;
}

int clsm330dlc_accel::get_struct_value(unsigned int struct_type , void *struct_values)
{
	if ( (struct_type & 0xFFFF) == 0x0001) {
		base_data_struct *return_struct_value = NULL;
		return_struct_value = (base_data_struct *)struct_values;
		if ( return_struct_value ) {
			return_struct_value->data_accuracy = 2;
			return_struct_value->data_unit_idx = IDX_UNIT_VENDOR_UNIT;
			return_struct_value->time_stamp = m_fired_time ;
			return_struct_value->values_num = 3;
			return_struct_value->values[0] = m_x;
			return_struct_value->values[1] = m_y;
			return_struct_value->values[2] = m_z;

			return 0;
		} else {
			ERR("return struct_value point error\n");
		}

	} else {
		ERR("Does not support type , struct_type : %d \n",struct_type);		
	} 
	return -1;
}

/**************************************
  check hardware node of sensor
  read kernel information and compaere
**************************************/
int clsm330dlc_accel::check_hw_node(void)
{
	...
	const char* orig_name = "lsm330dlc_accel";
	int find_node = 0;
  ...
			fp = fopen(name_node, "r");

			if (fp) {
				if ( fscanf(fp, "%s", hw_name) < 0) {
		
				fclose(fp);

				if (!strcasecmp(hw_name,orig_name)) {

	return find_node;
}

cmodule *module_init(void *win, void *egl)
{
	clsm330dlc_accel *sample;

	try {
		sample = new clsm330dlc_accel();
	} catch (int ErrNo) {
		ERR("clsm330dlc_accel class create fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
		return NULL;
	}

	return (cmodule*)sample;
}

void module_exit(cmodule *inst)
{
	clsm330dlc_accel *sample = (clsm330dlc_accel*)inst;
	delete sample;
}

//! End of a file

Filter Plugin

A passive component that converts sensor raw data to other types of data.

Prototype implementation filter plugin
class caccel:public csensor_module {
 public:
	/* Define enums*/
/* Define structures*/

	caccel();
	virtual ~ caccel();

	const char *name(void);
	int version(void);
	int id(void);

	bool is_data_ready(bool wait = false);

	long value(const char *port);
	long value(int id);

	bool update_name(char *name);
	bool update_version(int ver);
	bool update_id(int id);

	int port_count(void);
	const char *port(int idx);

	bool need_polling(void);
	long polling_interval(void);
	bool update_polling_interval(unsigned long val);
	int get_sensor_type(void);
	long set_cmd(int type, int property, long input_value);
	int get_property(unsigned int property_level, void *property_data);
	int get_struct_value(unsigned int struct_type, void *struct_values);

	int check_hw_node(void);

	bool start(void);
	bool stop(void);

	void reset(void);

 private:
/* Define private data structures and functions*/
}

Configuration

Sensor Framework loads configuration files sf_sensor.conf , sf_filter,conf , sf_processor.conf , sf_datastream.conf for loading sensor, filter, and processor plugins. All configuration files are included in sensor-framework package.

Each configuration file supports the following fields and values:

disable=yes/no   //enable or disable plugin             
override=yes/no  //if overide is yes, then id, version will be updated to below id, version
path=Absolute path of a component                                                          
id=decimal       // plugin ID
version=decimal  // plugin version
poll=deciamal(milli second) // default polling interval

Between [ and ], the names of plugin are placed. If don’t want to use the plugin, set disable to yes. If you want initialize polling interval for sensor, set poll time (ex. 100 means 100ms interval for polling)

Example of a sample sf_sensor.conf configuration file:

[accel_sensor]
disable=no
override=yes
path=/usr/lib/sensor_framework/libaccel.so                               
id=1111
version=1
poll=100
[geo_sensor]
disable=yes
override=yes
path=/usr/lib/sensor_framework/libgeo.so
id=1113
version=1 
poll=100

Example of a sample sf_processor.conf

[accel_processor]
path=/usr/lib/sensor_framework/libaccel_processor.so
id=2114
version=1
override=yes
disable=no

[gyro_processor]
path=/usr/lib/sensor_framework/libgyro_processor.so
id=2121
version=1
override=yes
disable=no

You don't need to edit datastream configure file.

Reference

Reference kernel configuration for sensors, will vary with different vendor types.

Sensor components Kernel Config Device nodes
Accelerometer CONFIG_INPUT_KR3DH /dev/input/event0/

/dev/input/event1/

/dev/input/event2/

/dev/input/event3/

/dev/input/event4/

/dev/input/event5/

Proximity CONFIG_INPUT_GP2A
Light sensor CONFIG_INPUT_GP2A
Electronic compass CONFIG_SENSORS_AK8975

Graphics and UI

This figure provides a brief overview of the Tizen UI and graphics architecture.

Graphicsarchitecture.png

Description

Tizen provides high performance 3D graphics as a component of UI & Graphics, as shown in the figure above. There are hardware-accelerated OpenGL ES (Open Graphics Library Embedded System) and EGL (Embedded-System Graphics Library) for 3D applications, such as 3D games.

OpenGL ES is an application programming interface (API) for advanced 3D graphics, targeted at handheld and embedded devices. To overcome device constraints, such as, limited processing capabilities and memory availability, it provides a subset of the functionality in OpenGL.

But embedded system-specific features were added to enhance rendering efficiency, such as, precision qualifiers to the shading language from OpenGL ES 2.0.

OpenGL

3D Graphics Library

The diagram provides an overview of the interface for Tizen high performance 3D graphics library with OpenGL.

Opengl.png

Description

EGL is a “glue” layer between OpenGL ES and the underlying native platform window system - X window system. EGL communicates with X Window to get information from the application window. And it creates a drawing surface and manages rendering context and resources.

Description of each component of 3D Graphics

OpenGL ES (Open Graphics Library Embedded System)
  • OpenGL is a software interface to graphics hardware.
  • It is designed as a hardware-independent interface to be used for many different hardware platforms.
  • OpenGL ES is a subset of the OpenGL designed for embedded systems.
  • OpenGL ES accepts primitives, such as points, lines, and triangles, and converts them into pixels using a graphics pipeline, known as the OpenGL state machine.
EGL (Embedded-System Graphics Library)
  • EGL is a (mostly) platform-independent API and an interface between rendering APIs, such as OpenGL ES or OpenVG and an underlying native platform window system.
  • It communicates with X window system, and creates drawing surfaces and manages rendering contexts.
  • EGLDisplay (X Display): Encapsulates all of the system dependencies for interfacing with the native windowing system.
  • EGLSurface: Encapsulates rendering destinations (window surface, pixmap surface), which are tied to X Window and X Pixmap.
  • EGLContext: Encapsulates OpenGL ES rendering context, which holds the state of GL server/client.

The following diagram gives a brief overview of EGL interface.

Egl interface.png

Porting

3D graphics vendors must provide these porting requirements for OpenGL ES/EGL:

OpenGL ES
  • The required version of OpenGL ES: 1.1 and 2.0
  • The driver must support the following extensions to OpenGL ES 1.1:
GL_OES_framebuffer_object
GL_OES_blend_subtract
GL_OES_blend_func_separate
GL_OES_matrix_palette
GL_OES_draw_texture
GL_OES_texture_cube_map
GL_OES_query_matrix
GL_OES_point_size_array
  • The driver must support the following extensions to OpenGL ES 2.0:
GL_OES_EGL_image
GL_EXT_texture_format_BGRA8888
GL_OES_get_program_binary
GL_OES_texture_npot
GL_OES_fragment_precision_high
GL_OES_rgb8_rgba8
GL_OES_depth24
GL_OES_vertex_half_float
GL_OES_texture_float
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_packed_depth_stencil
GL_OES_standard_derivatives
GL_OES_element_index_uint
GL_OES_mapbuffer
GL_EXT_multi_draw_arrays
GL_OES_vertex_array_object
GL_IMG_texture_compression_pvrtc
GL_OES_read_format
GL_EXT_multisampled_render_to_texture
  • You need some tools for generating a binary shader on Linux.
EGL

The minimum version required for EGL is 1.4. EGL must support DRI2.

  • Common 3D applications use DRI2 based EGL.
  • The 3D composite window manager needs DRI2 based EGL usually.
FBDEV based EGL( optional )
  • The FBDEV should consist of a triple buffer.
  • It should be performed with page flipping instead of copying the buffer.
  • To avoid tearing problem, perform with LCD vsync signal. Usually, compositor enables vsync using eglSwapInterval() API.
DRI2 based EGL( mandatory )
  • It’s a very important requirement.
  • It should be performed with X11 DRI2 protocol.
  • It should support texture from pixmap. (using EGL_KHR_image_pixmap and GL_OES_EGL_image)
GPU synchronization API
  • To avoid flickering, we need an internal EGL API, which is used to wait for completion of the buffer copy command.
Limitation of EGL surface
  • The FBDEV should consist of a triple buffer.
  • The driver must support the following extensions to EGL 1.4:
EGL_KHR_image
EGL_KHR_image_base
EGL_KHR_gl_texture_2D_image
EGL_KHR_gl_texture_cubemap_image
EGL_KHR_gl_renderbuffer_image
EGL_KHR_image_pixmap
EGL_KHR_lock_surface
EGL_KHR_fence_sync
EGL_KHR_reusable_sync
EGL_IMG_context_priority
   Need some method to allow the CPU to read and write the texture memory area of GPU
Header and Library name
Header files and libraries should be provided according to the Khronos API Implementers Guide. The following table gives a brief overview about the EGL library path and the respective header files.
LIBRARY PATH FILES
/usr/include/EGL egl.h

eglext.h

eglplatform.h

/usr/include/GLES gl.h

glext.h

glplatform.h

/usr/include/GLES2 gl2.h

gl2ext.h

gl2platform.h

/usr/include/KHR khrplatform.h
/usr/lib libEGL.so

libGLESv1_CM.so

libGLESv2.so

Note
You may need to implement some memory management techniques for sharing memory between your CPU and the graphics processing unit.

X server

X server is an X Window System display server that provides a basis for Graphical User Interface (GUI) and rich input capabilities for your system. It creates a hardware abstraction layer where software is written to use a generalized set of commands, allowing for device independence and reuse of programs on any system that implements X.

Input Driver

The following figure provides a basic introduction about X window system and X input driver.

Input.png

Description

X Window System
X Window system provides the interface for the manipulation of resources, which are windows, pixmap, gc, etc. X clients send the requests to the X server for drawing something or for manipulating windows. The X server accepts the clients’ requests and sends back replies to the requests. In addition, the X server sends X events when input events from input devices are pending or when X server encounters something that the X client may be interested in, such as configure or exposure events.
X server
The X server reads event(s) from the internal event queue and makes/sends X event(s) to the X client(s).
X input driver
X input driver reads input event stream from each input device node, makes X internal event(s), and put the event(s) into X server's internal event queue. For doing this, X input driver mainly uses interfaces implemented on xf86 DDX layer inside X server.
evdev driver
Implements for reading input event(s) stream originated from kernel evdev subsystem and for creating X internal event(s).
Supports device(s) such as keyboard, mouse, touchpad, touch screen, and so on.
evdev multi-touch driver
Implements for reading MT protocol event stream originated from kernel evdev subsystem, for interpreting them and for creating X internal event(s).
Supports touch screen device(s).

Porting OAL Interface

The following section provides a brief understanding about X server and X input driver.

Evdev module
An evdev contains these drivers
  • Driver for absolute pointing device like touch-screen.
  • Driver for relative pointing device like mouse.
  • Driver for key (board) device, including HW key and BT/USB keyboard.
Each driver sets up each input device, and will depends on X server's configuration.
  • After the device setup is done, the device reads input event(s) from device node, creates internal event(s) and put them in input event queue inside X server.
  • To make X input driver working, module must be loaded and must be registered as an input driver by X server.
  • Module, driver and device must provide following(s):
    • Module: module information.
    • Driver: driver information.
    • Device: read() for reading input event(s), proc() for controlling device status.
Refer to the following link, which contains information about the data structures and functions for each module and device.
http://www.x.org/wiki/Development/Documentation/XorgInputHOWTO
The module's basic information will be stored inside XF86ModuleData (xf86Module.h) and will be provided to X server.

Configuration

ServerFlags
  • AllowEmptyInput
"true" means that X server will be started without any keyboard/mouse driver.
  • AutoAddDevices
"false" means that hot plugged input device(s) will not be supported.
  • AutoEnableDevices
"true" means that 'DevicePresenceNotify event will be sent to all X client(s) by default.
InputClass
  • Identifier
sets unique input device name.
  • Driver
sets driver for device.
  • MatchDevicePath
sets path of device node to be handled by the device. Wildcard can be used.
  • Option
sets known option(s) and custom option(s) to be used inside driver for setting up device(s) or for
  • Enabling/disabling certain feature(s). Integer, Boolean, string type can be used.
  • MatchIsTouchScreen, MatchIsTablet, MatchIsPointer, MatchIsKeyboard
  • Checks that the found device matches one of above device type and sets the type for the device if matched.
Tizen extension for Evdev multi-touch driver
  • Provides one legacy single touch protocol
  • Provides two kinds of MT protocol
    • MT protocol A (which includes Tracking ID)
    • MT protocol B
  • Supporting new touch protocol can be done by one of followings:
    • Implementation of new touch protocol inside driver.
    • Cloning evdev multi-touch driver and implementation new touch protocol inside the driver.
    • Conversion from new protocol to existing protocol, which is supported by evdev multi-touch driver.

Video Driver

The following figure provides a brief overview about the X server and the X video driver.

Video.png

Description

X Window System
X Window system provides the interface for the manipulation of resources, which are windows, pixmap, gc, etc. X clients send the requests to X server for drawing something or for manipulating windows. X server accepts the clients’ requests and sends back replies to the requests. In addition, the X server sends X events to the client when input events from devices are pending or when X server encounters events that the X client may be interested, such as configure or exposure events.
X server
X server gets the requests from X clients and delivers them to the xf86 porting layer. Input events are processed by the X server and the X server sends them to the X clients.
X video driver
The X video driver is the driver library, which contains the implementation to support xf86 DDX layer, to display something to a screen.
  • Driver Module:
Implementation of a driver module for xf86 DDX.
  • Mode Setting:
Implementation for the devices to display images on it.
  • EXA:
Implementation for Graphic acceleration Architecture. Memory allocation and exa draw primitives.
  • DRI2:
Implementation for DRI2 (Direct Rendering Infrastructure ver.2).
  • XV:
XFree86 offers the X Video Extension (XV), which allows clients to treat video as any other primitive and ``Put video into drawables mode. By default, the extension reports no video adaptors as being available because the DDX layer has not been initialized.
Mode Setting
Kernel module for Display mode setting.
Functionality
  • Crtc control and management
  • Connector control and management
  • Encoder control and management
  • Framebuffer control and management
MemMgr
Kernel module for graphic memory management.
Functionality
  • control by mode setting
  • control by GPU
  • shared memory among processes
Device Driver
Video controller hardware to control the kernel side of the module.

Porting OAL Interface

The X video driver should implement the following driver module and extensions, using the interface provided by xf86 DDX and X extensions in the X server.

Driver Module
  • XF86ModuleData:
    • A symbol data which the X server finds when the X server load drivers.
    • The name of data is defined as modnameModuleData format. modname is the name of the X video driver.
Example: 

XF86ModuleData of sec_drv.so driver is defined below:
_X_EXPORT XF86ModuleData secModuleData = {&SECVersRec, SECSetup, NULL};

References Header: For xf86 header information, refer to this link:

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/common/xf86Module.h

To implement a driver module, refer to this link :

http://www.x.org/releases/X11R7.6/doc/xorg-server/DESIGN.txt

ScrnInfoPtr
  • The data structure should be initialized during the initialization of X video driver.
  • The probe functions are called when initializing the X server. The function pointers are mapped in the probe function of the X video driver.
  • The variables of ScrnInfoPtr set up by the function pointers of ScrnInfoPtr.
  • The function pointers of ScrnInfoPtr:
xf86ProbeProc *Probe
xf86PreInitProc *PreInit
xf86ScreenInitProc *ScreenInit
xf86SwitchModeProc *SwitchMode
xf86AdjustFrameProc *AdjustFrame
xf86EnterVTProc *EnterVT
xf86LeaveVTProc *LeaveVT
xf86ValidModeProc *ValidMode

References Header: For detailed header information, refer to this link:

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/common/xf86str.h

Mode Setting
  • xf86CrtcConfigPtr
    • The data structure contains the information of outputs, crtcs, and the configuration of outputs and crtcs.
    • The function pointers, which is xf86CrtcConfigFuncsRec *funcs, has to be set in the X video driver.
    • The function pointers of xf86CrtcConfigFuncsRec are:
Bool (*resize)(ScrnInfoPtr scrn, int width, int height);


References Header:

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/modes/xf86Crtc.h


  • xf86CrtcPtr
    • The data structure contains the information of a crtc.
    • The X video driver creates the number of instances of crtcs as the number of hardware crtcs.
    • The function pointers, which xf86CrtcFuncsRec *funcs, needs to be set in the X video driver.
    • The function pointers of xf86CrtcFuncsRec are :
Bool (*set_mode_major)(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y);
void (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
void (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
void (*show_cursor) (xf86CrtcPtr crtc);
void (*hide_cursor) (xf86CrtcPtr crtc);
void (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
void (*destroy) (xf86CrtcPtr crtc);

Reference Header

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/modes/xf86Crtc.h

  • xf86OutputPtr
    • The data structure contains the information of an output.
    • The X video driver creates the number of instances of outputs as the number of hardware connectors.
    • The function pointers, which xf86OutputFuncsRec *funcs, has to be set in the X video driver.
    • The function pointers of xf86OutputFuncsRec are:
void (*create_resources)(xf86OutputPtr output);
Bool (*set_property)(xf86OutputPtr output, Atom property, RRPropertyValuePtr value);
Bool (*get_property)(xf86OutputPtr output, Atom property);
xf86OutputStatus (*detect)(xf86OutputPtr output);
int (*mode_valid)(xf86OutputPtr output, DisplayModePtr pMode);
DisplayModePtr (*get_modes)(xf86OutputPtr output);
void (*destroy) (xf86OutputPtr output);

Reference Header

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/modes/xf86Crtc.h

EXA
  • ExaDriverPtr
    • The data structure contains the information on the X graphic acceleration.
    • It contains the functionality of memory allocation of pixmap private and EXA drawing primitives.
    • It contains the function pointers and the variables to be implemented by the X video driver.
    • The function pointers and variables of ExaDriverPtr are:
int exa_major, exa_minor;
CARD8 *memoryBase;
unsigned long offScreenBase;
unsigned long memorySize;
int pixmapOffsetAlign;
int pixmapPitchAlign;
int flags;
int maxX;
int maxY;
void    (*WaitMarker) (ScreenPtr pScreen, int marker);
Bool    (*PrepareAccess)(PixmapPtr pPix, int index);
void    (*FinishAccess)(PixmapPtr pPix, int index);
void *(*CreatePixmap)(ScreenPtr pScreen, int size, int align);
void (*DestroyPixmap)(ScreenPtr pScreen, void *driverPriv);
Bool (*ModifyPixmapHeader)(PixmapPtr pPixmap, int width, int height, int depth, int
bitsPerPixel, int devKind, pointer pPixData);
Bool    (*PixmapIsOffscreen)(PixmapPtr pPix);
Bool (*PrepareSolid) (PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg);
void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
void (*DoneSolid) (PixmapPtr pPixmap);
Bool (*PrepareCopy) (PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, int alu,
Pixel planemask);
void (*Copy) (PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int
height)
void (*DoneCopy) (PixmapPtr pDstPixmap);
Bool (*CheckComposite) (int op, PicturePtr pSrcPicture, Pictureptr pMaskPicture, PicturePtr
pDstPicture);
Bool (*PrepareComposite) (int op, , PicturePtr pSrcPicture, Pictureptr pMaskPicture,
PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr, pMask, PixmapPtr pDst);
void (*Composite) (PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY,
int width, int height);
void (*DoneComposite) (PixmapPtr pDst);
Bool (*UploadToScreen) (PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch);
Bool (*DownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch);

Reference Header

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=exa/exa.h

DRI2
  • DRI2InfoPtr
    • The data structure for DRI2 (Direct Rendering Infrastructure ver.2)
    • The role is management and control of DRI2 buffers.
    • It contains the function pointers and the variables to be implemented by the X video driver.
    • The function pointers and variables of DRI2InfoPtr are:
const char *driverName;
const char *deviceName;
int fd;
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
DRI2ScheduleSwapProcPtr ScheduleSwap;
DRI2GetMSCProcPtr GetMSC;
DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
DRI2AuthMagicProcPtr    AuthMagic;
DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;

Reference Header

http://source.tizen.org/git/?p=pkgs/xorg/server/xorg- server.git;a=blob;f=hw/xfree86/dri2/dri2.h

XV
  • XF86VideoAdaptor
    • XFree86 offers the X video extension, which allows clients to treat video as any other primitive and ``Put video into drawables. By default, the extension reports no video adaptors as being available because the DDX layer has not been initialized. The driver can initialize the DDX layer by filling out one or more XF86VideoAdaptorRecs, as described later in this document and passing a list of XF86VideoAdaptorPtr pointers to the following function:
Bool xf86XVScreenInit (ScreenPtr pScreen, XF86VideoAdaptorPtr *adaptPtrs, int num)
    • After doing this, the extension will report video adaptors as per the availability, provided the data in their respective XF86VideoAdaptorRecs was valid. Then xf86XVScreenInit() copies data from the structure passed to it, so that the driver may free it after the initialization. At the moment, the DDX supports only rendering into window drawables. Pixmap rendering will be supported after a sufficient survey of suitable hardware is completed. For more information, refer to this link: http://www.xfree86.org/current/DESIGN16.html#64
    • It contains the function pointers and the variables to be implemented by the X video driver.
    • The function pointers and variables of XF86VideoAdaptor are:
flags
name
nEncodings, pEncodings
nFormats, pFormats
nPorts, pPortPrivates
nAttributes, pAttributes
nImages, pImages
typedef int (*PutVideoFuncPtr)( ScrnInfoPtr pScrn, short vid_x, short vid_y, short drw_x, short drw_y, short vid_w, short vid_h, short drw_w, short drw_h, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
typedef int (*PutStillFuncPtr)( ScrnInfoPtr pScrn, short vid_x, short vid_y, short drw_x, short drw_y, short vid_w, short vid_h, short drw_w, short drw_h, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
typedef int (*GetVideoFuncPtr)( ScrnInfoPtr pScrn, short vid_x, short vid_y, short drw_x, short drw_y, short vid_w, short vid_h, short drw_w, short drw_h, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
typedef int (*GetStillFuncPtr)( ScrnInfoPtr pScrn, short vid_x, short vid_y, short drw_x, short drw_y, short vid_w, short vid_h, short drw_w, short drw_h, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
typedef void (*StopVideoFuncPtr)(ScrnInfoPtr pScrn, pointer data, Bool Exit)
typedef int (*SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data)
typedef int (*GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn, Atom attribute, INT32*value, pointer data)
typedef void (*QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn, Bool motion,short vid_w, short vid_h, short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h, pointer data)
typedef int (*PutImageFuncPtr)( ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int image, unsigned char* buf, short width, short height, Bool Sync, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw )
typedef int (*QueryImageAttributesFuncPtr)(ScrnInfoPtr pScrn, int image, unsigned short *width, unsigned short *height, int *pitches, int *offsets)

Reference Header http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/common/xf86xv.h

Configuration

None

References

OpenGL ES 1.X, 2.0 and EGL 1.4 API specifications are supported by Tizen. OpenGL ES/EGL APIs are managed by the Khronos group. For more information about OpenGL ES API and prototype, refer to the Khronos website (http://www.khronos.org/).

Xorg Input driver

http://www.x.org/wiki/Development/Documentation/XorgInputHOWTO


Khronos API Implementers Guide

www.khronos.org/registry/implementers_guide.pdf

X server
Base open source: xorg-server
Base version: 1.12.99.905 (Some patches have been added to 1.12.2)
Base URL: http://cgit.freedesktop.org/xorg/xserver/snapshot/xserver-6619f5c0e1086b57888ff7146e8ed5897b50d440.tar.gz
Xorg configuration
http://www.x.org/releases/X11R7.7/doc/man/man5/xorg.conf.5.xhtml
https://wiki.archlinux.org/index.php/Xorg
http://linux.die.net/man/5/xorg.conf
Evdev driver
Base open source: xf86-input-evdev
Base version: 2.3.2
Base URL: http://cgit.freedesktop.org/xorg/driver/xf86-input evdev/snapshot/xf86-input-evdev-2.3.2.tar.gz
Evdev multi-touch driver
Base open source: xf86-input-evdev
Base version: 2.3.1
Base URL: http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev/snapshot/xf86-input-evdev-2.3.1.tar.gz


Kernel configurations for input devices
CONFIGURATION PURPOSE
CONFIG_INPUT

CONFIG_INPUT_MISC

CONFIG_INPUT_EVDEV

For supporting input device
CONFIG_INPUT_EVDEV For evdev input system
CONFIG_INPUT_UINPUT For enabling input emulation
CONFIG_INPUT_TOUCHSCREEN For enabling touch screen
CONFIG_INPUT_KEYBOARD For enabling keyboard devices such as gpio-key, touch-key
CONFIG_KEYBOARD_GPIO For gpio-key
CONFIG_INPUT_MOUSEDEV

CONFIG_INPUT_MOUSE_PSAUX

For mouse devices

Multimedia

Camera

Description

The Multimedia camcorder framework controls the camera plugin of GStreamer to capture camera data from the device. But, the kernel interfaces to control the camera device could be different for different chipsets, so the camera HAL(Hardware Abstraction Layer) which is used by camera plugin is provided and it should be implemented specifically for each chipset. Each config file contains its own specific hardware dependent information. The Multimedia Camcorder framework reads and parses the information in these config files.

Tizen3.0 MMFWCamcorder.png

Camera source plugin for GStreamer

Gets camera data (preview or captured image) and sets various camera commands through camera HAL interface

Camera HAL

Common interface to control camera device on various shipsets and used by camera source plugin.

Config files

There are 3 config files for the Multimedia Camcorder framework, shown below and provided by “mmfw- sysconf-xxx”

  • mmfw_camcorder.ini - The camcorder settings file. It includes mainly the selection of plugins and settings, which are used by the camcorder framework and it defines the setting values or names of plugins, such as Video Input, Audio Input, Video Output, Video Encoder, and Audio Encoder
  • mmfw_camcorder_dev_video_pri.ini - This file includes the settings of the high resolution rear camera. Each item shows the value, which can be supported by the camera module.
  • mmfw_camcorder_dev_video_sec.ini - This file includes the settings of the low resolution front camera. Each item shows the value, which can be supported by the camera module.

Porting OAL Interface

GStreamer Camera plugin

Default reference camera source plugin which uses camera HAL interface is provided.

Camera HAL

mm-hal-interface package provides the header file of camera HAL.

  • repository path : platform/core/multimedia/mm-hal-interface
  • file name : tizen-camera.h
Major functions

Functions related to initialization and deinitialization

Prototype Description
int camera_init(void **camera_handle) Initializes new handle of camera HAL
int camera_deinit(void *camera_handle) Deinitializes handle of camera HAL

Functions related to open and close camera device

Prototype Description
int camera_open_device(void *camera_handle, int device_index) Opens camera device
int camera_close_device(void *camera_handle) Closes camera device

Functions related to get device information

Prototype Description
int camera_get_device_list(void *camera_handle, camera_device_list_t *device_list) Gets the device list of camera
int camera_add_message_callback(void *camera_handle, camera_message_cb callback, void *user_data, uint32_t *cb_id) Registers a callback function to be called to send a message by camera HAL
int camera_remove_message_callback(void *camera_handle, uint32_t cb_id) Unregisters a callback function

Functions related to preview and capture

Prototype Description
int camera_set_preview_stream_format(void *camera_handle, camera_format_t *format) Sets the format of the preview stream
typedef struct camera_format {
	camera_pixel_format_t stream_format;
	camera_resolution_t stream_resolution;
	uint32_t stream_fps;
	camera_rotation_t stream_rotation;
	camera_pixel_format_t capture_format;
	camera_resolution_t capture_resolution;
	uint32_t capture_quality;
} camera_format_t;
int camera_get_preview_stream_format(void *camera_handle, camera_format_t *format) Gets the format of the preview stream
int camera_start_preview(void *camera_handle, camera_preview_frame_cb callback, void *user_data) Starts preview frames on the screen
typedef int (*camera_preview_frame_cb)(camera_buffer_t *buffer, camera_metadata_t *meta, void *user_data);
int camera_stop_preview(void *camera_handle) Stops preview frames
int camera_release_preview_buffer(void *camera_handle, int buffer_index) Release the preview buffer. The preview buffer should be released with this function after use it.
int camera_start_auto_focus(void *camera_handle) Starts camera auto focusing operation
int camera_stop_auto_focus(void *camera_handle) Stops camera auto focusing operation
int camera_start_capture(void *camera_handle, camera_capture_cb callback, void *user_data) Starts capturing of still images
typedef int (*camera_capture_cb)(camera_buffer_t *main, camera_buffer_t *postview, camera_buffer_t *thumbnail, void *user_data);
int camera_stop_capture(void *camera_handle) Stops capturing of still images

Functions related to record video

Prototype Description
int camera_set_video_stream_format(void *camera_handle, camera_format_t *format) Sets the format of the video stream for recording
int camera_get_video_stream_format(void *camera_handle, camera_format_t *format) Gets the format of the video stream for recording
int camera_start_record(void *camera_handle, camera_video_frame_cb callback, void *user_data) Starts the video frame for recording
typedef int (*camera_video_frame_cb)(camera_buffer_t *buffer, camera_metadata_t *meta, void *user_data);
int camera_stop_record(void *camera_handle) Stops the video frame
int camera_release_video_buffer(void *camera_handle, int buffer_index) Release the video buffer. The video buffer should be released with this function after use it.

Functions related to control camera device

Prototype Description
int camera_set_command(void *camera_handle, int64_t command, void *value) Sets the various command and value to control camera device
#define CAMERA_COMMAND_BASE                     ((int64_t)1)
#define CAMERA_COMMAND_WHITE_BALANCE            ((int64_t)(CAMERA_COMMAND_BASE << 1))
#define CAMERA_COMMAND_ISO                      ((int64_t)(CAMERA_COMMAND_BASE << 2))
#define CAMERA_COMMAND_CONTRAST                 ((int64_t)(CAMERA_COMMAND_BASE << 3))
#define CAMERA_COMMAND_SATURATION               ((int64_t)(CAMERA_COMMAND_BASE << 4))
#define CAMERA_COMMAND_HUE                      ((int64_t)(CAMERA_COMMAND_BASE << 5))
#define CAMERA_COMMAND_SHARPNESS                ((int64_t)(CAMERA_COMMAND_BASE << 6))
#define CAMERA_COMMAND_EFFECT                   ((int64_t)(CAMERA_COMMAND_BASE << 7))
#define CAMERA_COMMAND_SCENE_MODE               ((int64_t)(CAMERA_COMMAND_BASE << 8))
#define CAMERA_COMMAND_EXPOSURE_MODE            ((int64_t)(CAMERA_COMMAND_BASE << 9))
#define CAMERA_COMMAND_EXPOSURE                 ((int64_t)(CAMERA_COMMAND_BASE << 10))
#define CAMERA_COMMAND_ROTATION                 ((int64_t)(CAMERA_COMMAND_BASE << 11))
#define CAMERA_COMMAND_FLIP                     ((int64_t)(CAMERA_COMMAND_BASE << 12))
#define CAMERA_COMMAND_FOCUS_MODE               ((int64_t)(CAMERA_COMMAND_BASE << 13))
#define CAMERA_COMMAND_FOCUS_RANGE              ((int64_t)(CAMERA_COMMAND_BASE << 14))
#define CAMERA_COMMAND_SHOT_MODE                ((int64_t)(CAMERA_COMMAND_BASE << 15))
#define CAMERA_COMMAND_ANTI_SHAKE               ((int64_t)(CAMERA_COMMAND_BASE << 16))
#define CAMERA_COMMAND_FOCUS_AREA               ((int64_t)(CAMERA_COMMAND_BASE << 17))
#define CAMERA_COMMAND_DIGITAL_ZOOM             ((int64_t)(CAMERA_COMMAND_BASE << 18))
#define CAMERA_COMMAND_OPTICAL_ZOOM             ((int64_t)(CAMERA_COMMAND_BASE << 19))
#define CAMERA_COMMAND_RECORDING_HINT           ((int64_t)(CAMERA_COMMAND_BASE << 20))
#define CAMERA_COMMAND_WDR                      ((int64_t)(CAMERA_COMMAND_BASE << 21))
#define CAMERA_COMMAND_SHUTTER_SPEED            ((int64_t)(CAMERA_COMMAND_BASE << 22))
#define CAMERA_COMMAND_FLASH_MODE               ((int64_t)(CAMERA_COMMAND_BASE << 23))
#define CAMERA_COMMAND_FACE_DETECTION           ((int64_t)(CAMERA_COMMAND_BASE << 24))
int camera_get_command(void *camera_handle, int64_t command, void *value) Gets the current value of command
int camera_set_batch_command(void *camera_handle, camera_batch_command_control_t *batch_command, int64_t *error_command) Sets a set of commands
typedef struct camera_batch_command_control {
	/* flag for modified command */
	int64_t command_set_flag;

	/* value list */
	camera_white_balance_t white_balance;
	int iso;
	int contrast;
	int saturation;
	int hue;
	int sharpness;
	camera_effect_t effect;
	camera_scene_mode_t scene_mode;
	camera_exposure_mode_t exposure_mode;
	int exposure;
	camera_rotation_t rotation;
	camera_flip_t flip;
	camera_focus_mode_t focus_mode;
	camera_focus_range_t focus_range;
	camera_exposure_mode_t shot_mode;
	int anti_shake;
	camera_rectangle_t focus_area;
	int digital_zoom;
	int optical_zoom;
	int recording_hint;
	int wdr;
	camera_flash_mode_t flash_mode;
	camera_face_detection_t face_detection;
} camera_batch_command_control_t;

Configuration

Config files
Read the keyword and its value from the file. Recognize the categories by using the keyword list of MSL camcorder, and save the member structure of MSL camcorder. Later, these values are used as attribute value or some other operation. The permission of this file is read-only to make sure the config files are read once before creating camcorder. Use a semicolon (“;”) to add comments in the config file.
Description of "mmfw_camcorder.ini"
Category Entry Description
[General] General setting or information
SyncStateChange API running type. It should be 1 (TRUE).
ModelName Model name of target.
[VideoInput] Setting list related with video input
UseConfCtrl whether to use config file or not. It should be 1 (TRUE).
ConfCtrlFile0 or 1 The name of setting file to control camera device.
VideosrcElement Source plugin which obtains camera input buffer from device.
UseZeroCopyFormat Whether to use zero copy format or not.
DeviceCount The number of camera device.
SupportMediaPacketPreviewCb Whether the camera API supports media packet preview callback or not on the target.
[AudioInput] Setting list related with audio input
AudiosrcElement Audio source plugin, which obtains audio for camcorder or voice record.
AudiomodemsrcElement Audio source plugin which obtains audio for call recording.
[VideoOutput] Setting list related with video output
DisplayDevice Supported output device list and default value.
Videosink Supported output surface list and default value.
VideosinkElementOverlay Plugin name for Overlay output surface and property setting list.
VideosinkElementEvas Plugin name for EVAS output surface and property setting list.
VideosinkElementGL Plugin name for GL output surface and property setting list.
VideosinkElementNULL Plugin name for NULL surface and property setting list.
[VideoEncoder] Define video encoder list for video recording
[AudioEncoder] Define audio encoder list for AV recording or voice recording
[Capture] Setting list related with image capture
UseEncodebin whether use “encodebin” to capture image or not. Recommend that keep this value as 0 (FALSE).
[Record] Setting value list for each recording mode. Recommend that keep values of example config file.
[Mux] Mux plugin list related with the file container.
Description of "mmfw_camcorder_dev_video_pri.ini" for primary camera (generally rear main camera) and "mmfw_camcorder_dev_video_sec.ini" for secondary camera (generally front sub camera).
Category Entry Description
[Camera] Describe the information
InputIndex Camera number to select (primary or secondary).
DeviceName Name of camera module.
PreviewResolution All supported preview resolution list that user can set and default values of this camera device.
CaptureResolution A list of all supported capture resolutions a user can set, as well as the default values for this camera device.
VideoResolution A list of all supported video resolutions a user can set, as well as the default value for this camera device.
FPS0 ~ 9 A list of all supported FPS (Frame Per Second) by preview resolution settings a user can use, as well as the default values for this camera device.
PictureFormat A list of all supported preview formats a user can set, as well as the default values for this camera device.
RecommendDisplayRotation Default display rotation value for displaying camera input.
RecommendPreviewFormatCapture Recommended preview format for capturing images.
RecommendPreviewFormatRecord Recommended preview format for recording.
RecommendPreviewResolution Recommended preview resolution by ratio of preview resolution.
FacingDirection The facing direction of camera device.
[Strobe] Settings about camera strobe(Flash)
StrobeMode Supported strobe mode and default values. This is converted to a real value and used in the kernel internally.
[Effect] Settings about the effects
Brightness Supported range of brightness and default values.
Contrast Supported range of contrast and default values.
Saturation Supported range of saturation and default values.
Sharpness Supported range of sharpness and default values.
Whitebalance Supported white balance list and default values. This is converted to real value used in kernel internally.
ColorTone Supported color tone list and default values. This is converted to a real value and used in the kernel internally.
WDR Supported Wide Dynamic Range mode list and default values. This is converted to a real value and used in the kernel internally.
[Photograph] Settings about camera shot
DigitalZoom Supported range of digital zoom level and default values.
OpticalZoom Supported range of optical zoom level and default values.
FocusMode Supported focus mode list and default value. This is converted to a real value and used in the kernel internally.
AFType Supported AUTO focus mode list and default values. This is converted to a real value and used in the kernel internally.
AEType Supported AUTO Exposure mode list and default value. This is converted to a real value and used in the kernel internally.
ExposureValue Supported range of exposure value and default values.
ISO Supported ISO list and default value. This is converted to a real value and used in the kernel internally.
ProgramMode Supported program mode (scene mode) list and default value. This is converted to a real value and used in the kernel internally.
AntiHandshake Supported anti-hand shake mode list and default value. This is converted to a real value and used in the kernel internally.
[Capture] Settings about image capture
OutputMode Supported capture format list and default values.
JpegQuality Supported range of JPEG quality and default values.
MultishotNumber Supported range of multi shot count and default values.
SensorEncodedCapture Whether the camera device supports encoded capture format(EX:JPEG) or not.
SupportHDR Supported HDR mode list and default value.
SupportZSL Whether the camera device suppors zero shutter lag capture or not.
[Detect] Settings about detect function
DetectMode Supported detect mode list and default values.

References

Driver Configuration
Set the kernel .config values for the camera like this:
CONFIG_VIDEO_DEV = y
CONFIG_VIDEO_SAMSUNG = y
CONFIG_VIDEO_SAMSUNG_V4L2 = y
CONFIG_VIDEO_FIMC = y
CONFIG_VIDEO_FIMC_MMAP_OUTPUT_CACHE = y
CONFIG_VIDEO_FIMC_MIPI = y
CONFIG_VIDEO_FIMG2D = y
CONFIG_VIDEO_JPEG = y
CONFIG_VIDEO_MFC5X = y
Kernel Node
For Camera		:   /dev/video1       
Other CAMIF interfaces	:   /dev/video(0-3)
GStreamer, refer to

http://gstreamer.freedesktop.org/documentation/ http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html

V4L2, refer to

http://v4l2spec.bytesex.org/spec-single/v4l2.html

Radio

Radio.png

Description

The radio interface part of the multimedia framework supports APIs to implement the following FM radio features. The interfaces to control the radio device are different each other. Therefore, Tizen provides Radio Hardware Abstraction Layer(HAL) to control various radio devices with common interface.

  • Tune a frequency
  • Get/Set a frequency
  • Scan all available frequencies
  • Seek up/down
  • Get frequency signal

Radio HAL

Common interface to control radio device on various chipsets and used by libmm-radio.

Porting OAL Interface

The OAL interface for FM radio is the radio HAL interfaces.

Radio HAL

mm-hal-interface package provides the header file of radio HAL.

  • repository path : platform/core/multimedia/mm-hal-interface
  • file name : tizen-radio.h

The OAL interface for FM radio is the Linux kernel V4L2 interfaces. The radio module directly uses the V4L2 ioctls, to perform various radio hardware configurations.

The reference section explains those V4L2 interfaces used by the FM radio interface.

Major functions

Fuctions related to initialization and deinitialization.

Prototype Description
radio_error_t radio_init(void **radio_hanle) Initializes new handle of radio HAL.
radio_error_t radio_deinit(void *radio_handle) Deinitializes handle of camera HAL

Funtions related to prepare and unprepare radio device

Prototype Description
radio_error_t radio_prepare_device(void *radio_handle) Prepare the device of radio.
radio_error_t radio_unprepare_device(void *radio_handle) Unprepare the device of radio

Functions related to open and close radio device

Prototype Description
radio_error_t radio_open_device(void *radio_handle) Opens the device of radio.
radio_error_t radio_close_device(void *radio_handle) Closes the device of radio

Functions related to start and stop radio device

Prototype Description
radio_error_t radio_start (void *radio_handle) Starts the device of radio
radio_error_t radio_stop (void *radio_handle) Stops the device of radio

Functions related to set / get frequency

Prototype Description
radio_error_t radio_get_frequency(void *radio_handle, uint32_t *frequency) Gets the radio frequency
radio_error_t radio_set_frequency(void *radio_handle, uint32_t frequency) Sets the radio frequency

Functions related to seek radio device

Prototype Description
radio_error_t radio_seek(void *radio_handle, radio_seek_direction_type_t direction) Seeks (up or down) the effective frequency of the radio, asynchronously
typedef enum radio_seek_direction_type {
RADIO_SEEK_DIRECTION_UP, /**< Seek upward */
RADIO_SEEK_DIRECTION_DOWN /**< Seek downward */

} radio_seek_direction_type_t;

Functions related to mute/unmute on radio device

Prototype Description
radio_error_t radio_mute(void *radio_handle) Sets the radio's mute
radio_error_t radio_unmute(void *radio_handle) Sets the radio's unmute

Functions related to get signal strength

Prototype Description
radio_error_t radio_get_signal_strength(void *radio_handle, uint32_t *strength) Gets the current signal strength of the radio

References

Kernel Node
For Radio		:   /dev/radio0       

Audio

Audio.png

Description

  • PulseAudio
    • PulseAudio is a sound server accepting sound input from one or more sources and redirecting it to one or more sinks. PulseAudio has these significant features:
      • Software mixing of multiple audio streams
      • Support for multiple audio sources and sinks
      • An extensible plugin architecture with support for loadable modules
      • Low-latency operation
      • Support external devices such as Bluetooth audio and USB audio devices.
    • Pulseaudio interacts with AudioHAL interfaces to support various type of devices.
  • AudioHAL
    • Predefined interfaces for Audio Hardware Abstraction Layer
    • Interface includes following categories : volume, route, stream, pcm
  • Configuration Files
    • Configurations for running Pulseaudio and Audio Systems which can be modified without code changes.
      • pulseaudio configurations (daemon.conf, client.conf, system.pa, etc.)
      • stream / device configuration (stream-map.json, device-map.json)

Porting OAL Interface

  • AudioHAL
Interface Description
audio_return_t audio_init(void **audio_handle) Initializes audio hal handle.
audio_return_t audio_deinit(void *audio_handle) De-initializes audio hal handle.
audio_return_t audio_get_volume_level_max(void *audio_handle, audio_volume_info_t *info, uint32_t *level) Gets the maximum volume level supported for a particular volume information.
audio_return_t audio_get_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t *level) Gets the volume level specified for a particular volume information.
audio_return_t audio_set_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t level) Sets the volume level specified for a particular volume information.
audio_return_t audio_get_volume_value(void *audio_handle, audio_volume_info_t *info, uint32_t level, double *value) Gets the volume value specified for a particular volume information and level.
audio_return_t audio_get_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t *mute) Gets the volume mute specified for a particular volume information.
audio_return_t audio_set_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t mute) Sets the volume mute specified for a particular volume information.
audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info) Updates the audio routing according to audio route information.
audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_t *option) Updates audio routing option according to audio route option.
audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected) Gets notified when a stream is connected and disconnected.
audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) Opens a PCM device.
audio_return_t audio_pcm_start(void *audio_handle, void *pcm_handle) Starts a PCM device.
audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle) Stops a PCM device.
audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle) Closes a PCM device.
audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *avail) Gets available number of frames.
audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void *buffer, uint32_t frames) Writes frames to a PCM device.
audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer, uint32_t frames) Reads frames from a PCM device.
audio_return_t audio_pcm_get_fd(void *audio_handle, void *pcm_handle, int *fd) Gets poll descriptor for a PCM handle.
audio_return_t audio_pcm_recover(void *audio_handle, void *pcm_handle, int revents) Recovers the PCM state.
audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods) Gets parameters of a PCM device.
audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods) Sets hardware and software parameters of a PCM device.

Configuration

To support a variety of devices, following configurations are needed to be modified by vendor.

  • PulseAudio configuration.
Configurations Description
/etc/pulse/daemon.conf Configuration file for the PulseAudio daemon.

In this file, pulseaudio daemon properties such as priority, log-level, resampling method, default samplerate, etc. can be modified.

In Tizen, pulseaudio daemon should be running as only system mode not user mode.

/etc/pulse/client.conf Configuration file for PulseAudio clients.

Not much needed for modification in general use case.

/etc/pulse/system.pa Pulseaudio Sound Server Startup Script.

This startup script is used only if PulseAudio is started in system mode.

Initial module loading is triggered by this file, so if there are some vendor specific modules to be loaded, they must be added here.

/etc/pulse/default.pa PulseAudio Sound Server Startup Script.

This startup script is used only if PulseAudio is started per user.

Currently Tizen doesn't support this mode.

  • Stream / Device configuration
    • Stream Map : Latency, Volume, Streams can be configured in this file.
    • Device Map : Device types and Device files can be configured in this file.

/ Device configuration

Configurations Example
/etc/pulse/stream-map.json
{
	"latencies":[
		{
			"type":"low",
			"fragsize-ms":25,
			"minreq-ms":-1,
			"tlength-ms":100,
			"prebuf-ms":0,
			"maxlength":-1,
		},
                ....
		{
			"type":"high",
			"fragsize-ms":75,
			"minreq-ms":-1,
			"tlength-ms":400,
			"prebuf-ms":0,
			"maxlength":-1,
		},
	],
	"volumes":[
		{
			"type":"media",
			"is-hal-volume":1,
		},
		{
			"type":"system",
			"is-hal-volume":0,
		},
		{
			"type":"notification",
			"is-hal-volume":0,
		},
		{
			"type":"ringtone",
			"is-hal-volume":0,
		},
		{
			"type":"call",
			"is-hal-volume":1,
		},
                ....
	],
	"streams":[
		{
			"role":"media",
			"priority" : 3,
			"route-type" : "auto",
			"volume-types":{"in":"none","out":"media"},
			"avail-in-devices":["audio-jack","builtin-mic"],
			"avail-out-devices":["forwarding","audio-jack","bt","builtin-speaker"],
			"avail-frameworks":["player","wav-player","tone-player","audio-io","recorder"],
		},
		{
			"role":"system",
			"priority" : 2,
			"route-type" : "auto",
			"volume-types":{"in":"none","out":"system"},
			"avail-in-devices":["none"],
			"avail-out-devices":["forwarding","audio-jack","bt","builtin-speaker"],
			"avail-frameworks":["player","wav-player","tone-player","audio-io"],
		},
		{
			"role":"notification",
			"priority" : 4,
			"route-type" : "auto-all",
			"volume-types":{"in":"none","out":"notification"},
			"avail-in-devices":["none"],
			"avail-out-devices":["audio-jack","bt","builtin-speaker"],
			"avail-frameworks":["player","wav-player","tone-player","audio-io"],
		},
		{
			"role":"ringtone-call",
			"priority" : 6,
			"route-type" : "auto-all",
			"volume-types":{"in":"none","out":"ringtone"},
			"avail-in-devices":["none"],
			"avail-out-devices":["audio-jack","bt","builtin-speaker"],
			"avail-frameworks":["player","wav-player","tone-player","audio-io"],
		},
		{
			"role":"call-voice",
			"priority" : 6,
			"route-type" : "manual",
			"volume-types":{"in":"none","out":"call"},
			"avail-in-devices":["builtin-mic","audio-jack","bt"],
			"avail-out-devices":["builtin-receiver","builtin-speaker","audio-jack","bt"],
			"avail-frameworks":["sound-manager"],
		},	
                ....	
	]
}
/etc/pulse/device-map.json
{
	"device-types":[
		{
			"device-type":"builtin-speaker",
			"builtin" : true,
			"direction":["out"],
			"avail-condition":["pulse"],
			"playback-devices":{"normal":"alsa:sprdphone,0", "call-voice":"alsa:VIRTUALAUDIOW,0"}
		},
		{
			"device-type":"builtin-mic",
			"builtin" : true,
			"direction":["in"],
			"avail-condition":["pulse"],
			"capture-devices":{"normal":"alsa:sprdphone,0"}
		},
		{
			"device-type":"audio-jack",
			"builtin":false,
			"direction":["both","out"],
			"avail-condition":["pulse","dbus"],
			"playback-devices":{"normal":"alsa:sprdphone,0", "call-voice":"alsa:VIRTUALAUDIOW,0"},
			"capture-devices":{"normal":"alsa:sprdphone,0"}
		},
		{
			"device-type":"bt",
			"profile":"a2dp",
			"builtin":false,
			"direction":["out"],
			"avail-condition":["pulse"]
		},
		{
			"device-type":"bt",
			"profile":"sco",
			"builtin":false,
			"direction":["both"],
			"avail-condition":["pulse","dbus"],
			"playback-devices":{"normal":"alsa:sprdphone,0", "call-voice":"alsa:VIRTUALAUDIOW,0"},
			"capture-devices":{"normal":"alsa:sprdphone,0"}
		},
		{
			"device-type":"usb-audio",
			"builtin":false,
			"direction":["both", "in", "out"],
			"avail-condition":["pulse"]
		}
                ....

	],
	"device-files":{
		"playback-devices":[
			{
				"device-string":"alsa:sprdphone,0",
				"role":{
						"normal":"rate=44100",
				}
			},
			{
				"device-string":"alsa:VIRTUALAUDIOW,0",
				"role":{
						"call-voice":"rate=16000 channels=1 tsched=0 alternate_rate=16000",
				}
			}
		],
		"capture-devices":[
			{
				"device-string":"alsa:sprdphone,0",
				"role":{"normal":"rate=44100"}
			}
		]
	}
}

References

Driver Configuration for Samsung chipset
Listed below is an example of the kernel .config values to be set for audio in the Samsung chipset.
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_HWDEP=y
CONFIG_SND_JACK=y
CONFIG_SND_SOC = y
CONFIG_SND_SOC_SAMSUNG = y
CONFIG_SND_SAMSUNG_I2S = y
CONFIG_SND_SOC_SLP_TRATS_MC1N2 = y
CONFIG_SND_SOC_I2C_AND_SPI = y
CONFIG_SND_SOC_MC1N2=y
PulseAudio
Version : 5.0
Website: http://www.freedesktop.org/wiki/Software/PulseAudio
ALSA
Website: http://www.alsa-project.org

Player

Player.png

Description

The multimedia player framework controls the player plugins (demuxer, codecs and renderer plugins) of GStreamer to play media content. But, the kernel interfaces to control codecs could be different for different chipsets, so corresponding codecs plugins should be implemented specifically for each chipset.

Porting OAL Interface

Playerplugin.png

There is no specific OAL for multimedia player framework. Player plugins, mentioned consist of the following components as part OAL interface: gst-openmax codec plugins, video/audio renderer plugins. Refer to OAL sections of Codecs for gst-openmax plugin details, Avsystem for audio (Porting_Guide/Multimedia#Audio), X11 (UI-framework) for display (Porting_Guide/Multimedia#Video).

Configuration

  • Config file
    • The multimedia player framework uses “mmfy_player.ini” config file to set various parameters for selecting different codecs/display plugins, etc.
    • “mmfy_player.ini” config file is provided by “mmfw-sysconf-xxx” package.
    • In the final stage of development, the permission for this file needs to be changed to read-only.
  • How to Configure
    • File name: mmfw_player.ini
    • One player.ini file is needed in each board (or model).
    • Codec plugins for this board are located in /usr/lib/gstreamer-0.10. Changing the codec plugin does not mean modifying this ini file because the player supports the auto plugin feature.
  • As needed, these following setting values can be used for developing
    • element exclude keyword
      • A general section keyword, it means that these codec plugins do not link in the player pipeline. The default value is ffdec_
      • If you want to use the ffmpeg s/w codec plugin for testing, you can remove this ffdec_ keyword.
      • If there are many codec plugins which have the same rank and same feature, it causes problems to select the codec you want. So you need to add the plugin name to exclude unwanted plugins.
    • video converter element
      • The default is the ffmpegcolorspace plugin. If you do not want this plugin, you can remove it, and change it to another converter plugin.
    • audio filter
      • By default, the s/w audio effect plugins based on arm architecture are used. So, if the platform is set to another architecture process, this value needs to be set to false. And, How to make and use such plugin is under the review.

References

Display Driver Configuration for Samsung chipset
Listed below is an example of the kernel .config values to be set for display in the Samsung chipset:
CONFIG_DRM =  y
CONFIG_FB  = y
CONFIG_FB_S3C = y
CONFIG_FB_S3C_LCD_INIT = y
CONFIG_FIMD_EXT_SUPPORT = y
CONFIG_FIMD_LITE_SUPPORT = y
Kernel Node
Frame buffers- /dev/fb(0-4)

Codec

Codec.png

Shows two types of codec plugins, such as gstreamer type and OpenMAX type codec plugin.

Description

  • Gstreamer codec plugin
    • Gstreamer codec plugin can be linked and used easily to gstreamer pipeline, which is used in multimedia FW.
  • OpenMAX codec plugin
    • Some of the codec vendors provide OpenMAX IL components and not Gstreamer plugins, Tizen provides gst-omx plugins to use OpenMAX IL components.
    • Gstreamer pipeline, which is used in Multimedia FW can control and transfer data to OpenMAX IL component using gst-omx plugin.
Description of each component of codec
  • Gstreamer codec plugin

Gstreamer codec plugin.png

Figure 2. Shows the example of decoder codec plugin, which is provided as a gstreamer element. If the codec plugin is provided, the player can link this plugin to its pipeline immediately.

  • For detailed information about gstreamer usage, go to reference section.
  • In addition, to link a gstreamer pipeline, the capability of codec plugin can be negotiated with the linked element in the pipeline.
  • To know detailed information, such as capability of an element, we can use “#gst-inspect (element name)” command.

Gst-inspect.png

  • OpenMAX component codec plugin

Openmax.png

Figure 3 shows the example of decoder codec plugin, which is provided as an OpenMAX component type.

  • To use OpenMAX component in gstreamer, we provided the gst-openmax (open source) package. By using this package, gstreamer can recognize and use an OpenMAX component as a gstreamer element.
  • Gst-openmax is a gstreamer plugin that allows communication with OpenMAX IL components. The usage of this gst-openmax plugin is the same as other gstreamer plugins, but if you want more detailed information about this plugin, you can refer this web site:

http://www.freedesktop.org/wiki/GstOpenMAX

  • If you want to know about OpenMAX IL, please refer to this web site:

http://www.khronos.org/openmax/

  • As shown Figure 1, gst-openmax plugin refers to a configuration file: gst-openmax.conf. This file is included in mmfw-sysconf package, and installed to /usr/etc/gst-openmax.conf in target device.

Porting OAL Interface

OpenMAX Component Codec Plugin
  • An industry standard that provides an abstraction layer for computer graphics, video, and sound routines.
  • The interface abstracts the hardware and software architecture in the system.
  • The OpenMAX IL API allows the user to load, control, connect, and unload the individual components. This flexible core architecture allows the Integration Layer to easily implement almost any media use case and mesh with existing graph-based media frameworks.
  • The key focus of the OpenMAX IL API is portability of media components
  • OpenMAX IL interfaces between media framework, such as GStreamer and a set of multimedia components (such as an audio or video codecs).
  • gst-omx is a GStreamer plug-in package that allows communication with OpenMAX IL components.
  • Gst-omx structuring is classified into different object classes based on the functionality. The following is the object structuring of a video decoder plugin in gst-omx:

Gst-omx.png

  • The GstVideoDecoder base class is for video decoers provide encoded data to derived GstOMXVideoDec and each input frame is provided in turn to the subclass's handle_rame callback.
  • The GstVideoDecoder base class and derived subclass cooperate as follows
1. Configuration
  - GstVideoDecoder call start() when the decoder element is activated.
  - GstVideoDecoder calls set_format() to inform the subclass of caps describing input video data
2. Data processing 
   - Each input frame is provided in turn to the subclass's handle_frames()
   - The subclass call gst_video_decoder_finish_frame() or gst_video_decoder_drop_frame()
3. Shutdown phase
   - The GstVideoDecoer class calls stop()

Configuration

  • OpenMAX component codec plugin
    • OpenMAX component codec plugin cannot be linked to gstreamer directly. Hence, we use gst-omx plugin to link OpenMAX component and gstreamer.
    • Gst-omx is a gstreamer plugin that allows communication with OpenMAX IL components.
    • Gst-omx plugin refers a configuration file, such as gstomx.conf. This file is included in gst-omx package, and installed /etc/xdg/gstomx.conf in target device.
  • This file needs to change appropriately, according to vendors which provide OpenMAX component.
    • gstomx.conf
      • The following values of each item in the lists separated by commas.
      • Each gstreamer element is separated by a semicolon.

Gst-openmax.conf.png

Example:

Omx mpeg4dec.png

      • Each value needs to be changed appropriately, according to vendors which provide OpenMAX component.
      • When you finished these settings, the other is same as gstreamer type codec plugin. Hence, you can test this codec same way.
  • Use of codec plugin in Player
    • Because the player uses auto plugging, it doesn’t need an additional setting.
      • If the decoder plugin has acceptable capability, this plugin can be linked with a player pipeline in order of rank.
      • If the codec name is included in the excluded keyword in /usr/etc/mmfw_player.ini (mmfw-sysconf package), it will be excluded in player pipeline.
  • Use of codec plugin in Camcorder
    • Because camcorder clarified its audio, video, and image encoder in /usr/etc/mmfw_camcorder.ini file (mmfw-sysconf package), you need to change this category value to set your own codec name.

Videoencoder.png

References

Connectivity

Bluetooth

Bluetooth is the short range communication used to communicate between two devices. In Tizen, we use open source Bluetooth components like Bluez and Obexd. Bluez and Obexd run as the daemon and there will be an interface library Bluetooth Framework, used for applications to access Bluez or Obexd over D-Bus interface.

This section explains the Bluetoooth architecture on the Tizen platform and how Tizen can be ported, along with the configuration parameters and its values.

The below figure explains the Bluetooth architecture on Tizen.

Bluetooth Low Energy function was implemented in bluez & bluetooth-frwk.

Bluetooth.png

  • Bluetooth version supported - Bluetooth 4.2
  • Profiles supported - GATT, FTP, OPP, MAP, PBAP, A2DP, AVRCP, HSP/HFP, RFCOMM, HID, HDP, PAN profiles are supported.
  • Application Definition: Provides Dialogue for user. It controls BlueZ/ObexD/PulseAudio Daemon.
  • BT Framework
    • Tizen BT is based on the Open Source BlueZ Project. BlueZ provides DBUS API and based on it, Tizen BT framework provides the C Language API, we recommend application developers use our BT framework.
    • BT provides a standard interface between BT chip and AP, called the HCI (Host Controller Interface). HCI can be implemented on USB, UART, SDIO, but for the mobile environment, UART is used most.
  • Depending on the Chip Vendor, HCI Interface Activation could be different. The vendor would provide HCI Configuration and initial scripts
    • Ex> Broadcom and Spreadtrum: Those provide firmware and a loading tool.

Description

  • Application
    • This is a user dialogue that controls the BlueZ/ObexD/PulseAudio Daemon
  • ObexD
    • ObexD is the open souce component
    • Object exchange daemon
    • Supports OPP, FTP, PBAP, SYNC, MAP profile stack
  • BluetoothD
    • Bluetoothd is the open souce component, Bluez 5.37 is supported
    • Bluetooth central daemon
    • Support GAP, SDP, A2DP, AVRCP, HFP, HSP, GATT profile stack
  • Bluetooth Subsystem
    • Provide BT unix socket. Each protocol can be accessed by it’s socket.
    • Protocol - L2CAP, RFCOMM, SCO, HCI
  • Bluetooth Driver
    • BT Chip Driver
    • In case of UART, Linux kernel provides the interface.
    • GPIO configuration, rfkill (Radio Frequency Management) and power management can be handled by both the vendor and the porting engineer.
  • BT Firmware Loading Module
    • Depending on the environment, it loads BT firmware to BT chip.
    • Tizen and chipset vendor need to implement this together.
    • Package : bluetooth-tools

Porting OAL Interface

The following OAL scripts are run during BT stack start and end sequences. These scripts will invoke BT chip specific (such as Broadcom and Spreadtrum) scripts, provided by the chipset vendor to perform chip specific configuration and these scripts are available with bluetooth-dev-tools.under. When this package is installed, it copies these scripts under /usr/etc/Bluetooth/.

  • bt-stack-up.sh – This script file is used to run the hardware specific script file/files to power up or start BT hardware along the background processes, such as bluez and obexd.
  • bt-stack-down.sh – This script file is used to run the hardware specific script file/files to power down or stop BT hardware along with the background processes, such as bluez and obexd.
  • bt-reset-env.sh – This script file is used to reset the BT chip by running bt-stack-down.sh along with resource clean up.
Tizen BT Obex profiles
In Tizen, for the obex based profiles, we are using the obexd opensource.
  • BT Obex profiles server (obexd)
   obexd –d –noplugin=syncevolution,pcsiut,irmc –symlinks –r /ftp_ folder
  • BT Obex profiles client (obex-client)
   obex-client

Configuration

There are a few configuration changes that need to be made to enable the specific chipset and the scripts and other configuration information, like UART speed, UART terminal (tty) to be opened specific to the chipset. These changes should be provided by the chipset vendors.

Below is the example of BCM4358 Bluetooth chipset by Broadcomm.
  • hciattach - Project bluez/tools/hciattach.c is patched to enable the BCM4358 chipset specific hciattach tool. This service attaches the BT UART HCI interface to the bluetooth stack at baud rate of 3000000. It is also responsible for loading the BT firmware on BCM4358.
  • The Bluetooth UART used is /dev/ttySAC3
  • The Broadcom firmware used is BCM4358A1_001.002.005.0032.0066.hcd
  • The UART speed configuration is 3000000 for BCM4358A1
  • The bcmtool used is bcmtool_4358a1
  • The .bd_addr contains the unique bluetooth address, which is generated during first bluetooth activation
  • How to register the bluetooth device:
   bcmtool_4358a1 /dev/ttySAC0 –FILE=BCM4358A1_001.002.005.0032.0066.hcd –BAUD=3000000 –ADDR=/csa/bluetooth/.bd_addr –SETSCO=0,0,0,0,0,0,0,3,3,0 –LP
  • Attaching a serial device using UART HCI to the bluetooth stack for a broadcom device
   hciattach /dev/ttySAC3 –S 3000000 bcm2035 3000000 flow
  • Running the bluetooth daemon version 5.37
   bluetoothd 
  • Device up and setting up the device name, SSP mode enabling
hciconfig hci0 up
hciconfig hci0 name “Tizen-Mobile”
hciconfig hci0 sspmode 1
  • Turn on the bluetooth radio
   rfkill unblock bluetooth 
  • Turn off the bluetooth radio
   rfkill block bluetooth
Below is the example of sc2331 Bluetooth chipset by Spreadtrum.
  • hciattach - Project bluez/tools/hciattach.c is patched to enable the sc2331 chipset specific hciattach tool. This service attaches the BT UART HCI interface to the bluetooth stack at baud rate of 3000000. It is also responsible for loading the BT firmware on sc2331.
  • How to register the bluetooth device:
   cp2-download is the tool for downloading firmware provided with spredtrum. This tool also downloads wifi firmware at the booting time.
  • At a target, these files should be installed in /usr/lib/firmware
   sc2331_fdl.bin
   sc2331_fw.bin
   scx35_pikeavivaltove_3M_MARLIN_connectivity_calibration.ini
   scx35_pikeavivaltove_3M_MARLIN_connectivity_configure.ini
  • The Bluetooth UART used is /dev/ttyS0.
  • The UART speed configuration is 3000000 for sc2331.
  • Attaching a serial device using UART HCI to the bluetooth stack
   hciattach -s 3000000 /dev/ttyS0 sprd 3000000 flow
  • Running the bluetooth daemon version 5.37
   bluetoothd 
  • Device up and setting up the device name, SSP mode enabling
hciconfig hci0 up
hciconfig hci0 name “Tizen-Mobile”
hciconfig hci0 sspmode 1

References

Open source components versions : BlueZ 5.37

Reference: http://www.bluez.org/

Reference kernel configuration for BT

The following kernel .config are enabled for Broadcom Bluetooth support:

   CONFIG_BT=y
   CONFIG_BT_L2CAP=y
   CONFIG_BT_RFCOMM=y
   CONFIG_BT_RFCOMM_TTY=y
   CONFIG_BT_BNEP=y
   CONFIG_BT_HIDP=y
   CONFIG_BT_HCIUART=y
   CONFIG_BT_HCIUART_H4=y
   CONFIG_BCM4330=y
   CONFIG_RFKILL=y
   CONFIG_RFKILL_INPUT=y
   CONFIG_RXTRA_FIRMWARE_BCM4330=”BCM4330.hcd”

The following kernel .config are enabled for Bluetooth AVRCP support:

   CONFIG_INPUT_MISC=y
   CONFIG_INPUT_UINPUT=y

The following kernel .config are enabled for Bluetooth HID support:

   CONFIG_INPUT_GP2A=y
   CONFIG_INPUT_KR3DH=y

The following kernel .config are enabled for Bluetooth Audio (SCO-over-PCM) support:

   CONFIG_BT_SCO=y
   CONFIG_INPUT_GP2A=y
   CONFIG_INPUT_KR3DH=y

The following kernel .config are enabled for Bluetooth Audio (SCO-over-PCM) support:

   CONFIG_BT_SCO=y

WLAN

Description

Wlan.png

This section of the guide provides a step-by-step explanation of what's involved in adding a new Wi-Fi driver and making Wi-Fi work.

Feature Overview:

  • WLAN (802.11 b/g/n)
  • WPS PBC
  • EAP (PEAP, TTLS)

TIZEN uses wpa_supplicant as the platform interface to the Wi-Fi device. Your Wi-Fi driver must be compatible with the standard wpa_supplicant.

The TIZEN WLAN architecture is centered on the Linux wireless (IEEE-802.11) subsystem (Reference 2). The Linux wireless SW stack defines the WLAN HW adaptation SW interfaces that need to be used in TIZEN. In practice, the required interfaces are defined by cfg80211 for FullMAC WLAN devices and by mac80211 for SoftMAC WLAN devices. In addition, a Linux network interface needs to be supported towards the Linux TCP/IP stack.

Connection Manager (ConnMan) is a daemon for managing internet connections within embedded devices running the Linux operating system.

WPA Supplicant: wpa_supplicant is a WPA Supplicant with support for WPA and WPA2 (IEEE 802.11i / RSN). Supplicant is the IEEE 802.1X/WPA component that is used in the client stations. It implements key negotiation with a WPA Authenticator and it controls the roaming and IEEE 802.11 authentication/association of the WLAN driver (Reference 3).

Porting OAL Interface

WLAN Driver plugin is specific to a Wi-Fi chipset. This includes firmware and tools specific to Wi-Fi chipsets. Wi-Fi chipset firmware and tools files should be copied to WLAN driver plugin directory, build, and installed before testing Wi-Fi functionality.

The WLAN driver plugin contains a file called wlan.sh (/usr/bin/wlan.sh), which is used to load or unload Wi-Fi driver firmware.

When wifi_activate() is called, the load driver request is sent to the NET-CONFIG daemon. The NET-CONFIG daemon load Wi-Fi driver using the wlan.sh script file. Similarly, the wifi_deactivate() API requests unloading of the Wi-Fi driver. In case Wi-Fi Direct, wifi_direct_activate() and wifi_direct_deactivate() API make Wi-Fi Direct Manager to load or unload Wi-Fi driver using wlan.sh.

Wi-Fi driver should create /opt/etc/.mac.info file, which has MAC address of device, because of Tizen platform's requirement.

Turning Wi-Fi ON/OFF:

Usage of /usr/bin/wlan.sh script
wlan.sh start : Power up the Wi-Fi driver in station mode by loading the driver and running the firmware file.
wlan.sh p2p : Power up the Wi-Fi driver in Wi-Fi Direct mode by loading the driver and running the firmware file.
wlan.sh softap : Power up the Wi-Fi driver in Soft AP mode by loading the driver and running the firmware file.
wlan.sh stop : Power down the Wi-Fi driver.

All other Wi-Fi related functionality is handled by the ConnMan daemon

Configuration

None

References

Reference kernel configurations
  • These options need to be enabled if the driver supports the cfg802.11 configuration API, instead of the wireless extension API. (Refer to: http://linuxwireless.org).
   CONFIG_CFG80211
   CONFIG_LIB80211
   CONFIG_MAC80211 (Enable this flag, if the driver supports softMAC feature).
  • On the other hand, the configuration options below should be enabled in the kernel if the driver supports wireless extension APIs.
   CONFIG_WIRELESS_EXT=y
   CONFIG_WEXT_CORE=y
   CONFIG_WEXT_PROC=y
   CONFIG_WEXT_PRIV=y
   CONFIG_WEXT_SPY=y
   CONFIG_WIRELESS_EXT_SYSFS=y

NFC

Description

Nfc.png

  • The NFC application enables the user to read and/or import the content written on an NFC tag, edit the content written on an NFC tag, write and save data in an NFC tag, and load and save the NFC data from or in a file.
  • The NFC client acts as an interface between the NFC app and the NFC manager, while writing or editing tag information in any physical tag.
  • The NFC manager is the main interface, which actually deals with NFC physical tags, creates a connection with tags and detects it. It’s a daemon process to control the NFC chipset (such as NXP pn544). It provides Tag read/write service and basic P2P communication service. It provides basic API to client application.
  • The NFC stack contains the required plugin, based on the NFC chipset. Currently, nfc-plugin-nxp is used for the NXP chipset.
  • The NFC plugin acts as an interface between the NFC chipset with the NFC framework (nfc-manager). It should implement according to the interface provided by the nfc-manager.

Porting OAL Interface

The NFC plugin is implemented as a shared library and it interfaces the TIzen nfc-manager and the vendor NFC chip. The NFC manager will load the libnfc-plugin.so library at run time from “/usr/lib/libnfc-plugin.so”. Any vendor-specific plugin will be installed within the same path. The plugin should be written with predefined OAL API interfaces.

During initialization, the nfc-manager loads the nfc-plugin.so, searches for the ‘onload’ API, and calls the ‘onload’ API with an interface structure instance as an argument for mapping of all the OAL interfaces. These OAL/OEM interfaces are implemented according to the underlying NFC chipset. Once the mapping is done, the NFC manager will interact with nfc-plugin, which implements the vendor specific OAL interfaces.

'onload' function for reference :

Bool onload(net_nfc_oem_interface_s *oem_interfaces)
{
 oem_interfaces->init = xxx;  // xxx refers to plugin APIs
 oem_interfaces->deinit = xxx;
 oem_interfaces->register_listener = xxx;
 oem_interfaces->unregister_listener = xxx;
 oem_interfaces->check_firmware_version = xxx;
 ......
 
 return true;
}

The NFC OAL interfaces are defined in this structure:

Ref er net_nfc_oem_controller.h
typedef struct _net_nfc_oem_interface_s
{
 net_nfc_oem_controller_init init;
 net_nfc_oem_controller_deinit deinit;
 net_nfc_oem_controller_register_listener register_listener;
 net_nfc_oem_controller_unregister_listener unregister_listener;
 net_nfc_oem_controller_check_firmware_version check_firmware_version;
 net_nfc_oem_controller_update_firmware update_firmeware;
 net_nfc_oem_controller_get_stack_information get_stack_information;
 net_nfc_oem_controller_configure_discovery configure_discovery;
 net_nfc_oem_controller_get_secure_element_list get_secure_element_list;
 net_nfc_oem_controller_set_secure_element_mode set_secure_element_mode;
 net_nfc_oem_controller_connect connect;
 net_nfc_oem_controller_connect disconnect;
 net_nfc_oem_controller_check_ndef check_ndef;
 net_nfc_oem_controller_check_target_presence check_presence;
 net_nfc_oem_controller_read_ndef read_ndef;
 net_nfc_oem_controller_write_ndef write_ndef;
 net_nfc_oem_controller_make_read_only_ndef make_read_only_ndef;
 net_nfc_oem_controller_transceive transceive;
 net_nfc_oem_controller_format_ndef format_ndef;
 net_nfc_oem_controller_exception_handler exception_handler;
 net_nfc_oem_controller_is_ready is_ready;
 net_nfc_oem_controller_llcp_config config_llcp;
 net_nfc_oem_controller_llcp_check_llcp check_llcp_status;
 net_nfc_oem_controller_llcp_activate_llcp activate_llcp;
 net_nfc_oem_controller_llcp_create_socket create_llcp_socket;
 net_nfc_oem_controller_llcp_bind bind_llcp_socket;
 net_nfc_oem_controller_llcp_listen listen_llcp_socket;
 net_nfc_oem_controller_llcp_accept accept_llcp_socket;
 net_nfc_oem_controller_llcp_connect_by_url connect_llcp_by_url;
 net_nfc_oem_controller_llcp_connect connect_llcp;
 net_nfc_oem_controller_llcp_disconnect disconnect_llcp;
 net_nfc_oem_controller_llcp_socket_close close_llcp_socket;
 net_nfc_oem_controller_llcp_recv recv_llcp;
 net_nfc_oem_controller_llcp_send send_llcp;
 net_nfc_oem_controller_llcp_recv_from recv_from_llcp;
 net_nfc_oem_controller_llcp_send_to send_to_llcp;
 net_nfc_oem_controller_llcp_reject reject_llcp;
 net_nfc_oem_controller_llcp_get_remote_config get_remote_config;
 net_nfc_oem_controller_llcp_get_remote_socket_info get_remote_socket_info;
 net_nfc_oem_controller_sim_test sim_test;
 net_nfc_oem_controller_test_mode_on test_mode_on;
 net_nfc_oem_controller_test_mode_off test_mode_off;
net_nfc_oem_controller_support_nfc support_nfc;
} net_nfc_oem_interface_s;

The nfc_oem_interface_s is exported in the nfc-plugin. Using this interface structure, the nfc-manager communicates with the OAL interfaces at run time. The NFC plugin will load when the nfc-manager is started and the plugin init() function will be called. The init function will initialize the NFC chip.

   int (*init) (net_nfc_oem_controller_init*) ;

This is the deinit() function the nfc-manager issues to de-initialize the NFC chip:

   int (*deinit) (net_nfc_oem_controller_deinit *);
Sending the Notification to upper Layer (NFC Service)
Please, you can refer the phdal4nfc_message_glib.c. We use the g_idle_add_full for handling the message in NFC Service. So we can use the callback client asynchronously in the client context. We post a message in queue. The message will be processed by a client thread.
Reference implementation of NFC plugin
Sample code snippets cannot be reproduced. Code is proriatory.
You can refer nfc-plugin-emul and nfc-plugin-nxp.


Configuration

The nfc-plugin package should be saved to ‘/usr/lib/libnfc-plugin.so’ at install time. When nfc-manager starts, it looks for the plugin library and loads the it dynamically from this path.


References

Kernel Config

 Using Pn544 : CONFIG_PN544_NFC
 Using Pn65n : CONFIG_PN65N_NFC

API references available are under the Porting_Guide/Appendix

LINKS


MTP

Description

  • MTP exchanges may only occur between two products at a time, and in each communication, one product acts as the Initiator and the other as the Responder.
  • The Initiator is the product that initiates actions with the responder by sending operations to the Responder.

Mtp-initiator.png

  • The Responder may not initiate any actions, and may only send responses to operations sent by the Initiator or send events.

Mtp-responder.png

  • In Tizen system, the USB Host is Initiator, and the USB Device is the Responder.


Porting OAL Interface

  • Tizen MTP Initiator / Responder has not OAL Interface.
  • But, There is a extension possibilities of the MTP Transport layer.


Configuration

MTP Initiator
  • MTP Initiator consist of 3 packages.
   mtp-initiator daemon
   mtp-initiator api
   libmtp opensource
  • mtp initiator does not operate independently. It requires the help of another module. (ex) usb module
  • When the usb device is connected to the host, The module must run the mtp initiator daemon.
MTP Responder
  • MTP Responder consist of 1 package.
   mtp-responder daemon
  • mtp responder does not operate independently. It requires the help of another module. (ex) usb module
  • When the usb device is connected to the host, The module must run the mtp responder daemon.

References

Location

Location.png

Description

Location provides location based services (LBS) including the position information, satellite information and GPS status.

Features Overview
  • GPS (Global positioning system).
  • Getting the current position, last known position, accuracy, distance and velocity.
  • Getting the satellite information of GPS and GLONASS.
  • Notifying a user when they enter or exit a predefined set of boundaries, known as geo-fence, like school attendance zones or neighborhood boundaries.
Location framework Description
  • Native Locations:
Tizen gives applications access to the location services supported by the device through the native locations, which provides API’s to determine location and bearing of the underlying services (if available).
  • Location Library:
    • This contains the location providers that can be used by the native locations to get the services.
    • GPS
      • GPS provides position information, velocity and satellite information. It is used to get current position of a device.
  • Lbs dbus:
    • This is the IPC used to communicate between location module and the GPS Manager daemon.
  • GPS Manager:
    • GPS Manager provides position, velocity, NMEA and satellite information by communicating with a GPS chip.
    • Functionalities of GPS Manager
      • GPS initialization/de-initialization and open/close control.
      • Provides the position result for location library.
      • Location session management-determination for session termination based on session status.
      • Serial interface with the GPS receiver.
      • Enables GPS chipset to support standalone GPS positioning methods.
      • Supported Operation modes.
        • Standalone:
          • A GPS receiver device in which the receiver provides all of its own data needs and performs all position calculations, without connection to an external network or server.

Porting OAL Interface

The GPS plugin is implemented based on Tizen GPS manager for vendor specific GPS device.

The GPS plugin is implemented as a shared library and the gps-manager loads a specific GPS plugin at runtime. A GPS plugin should be written with predefined interfaces. The gps-manager-plugin-dev source package is installed on OBS by adding the following command in the package spec file.

BuildRequires: pkgconfig(gps-manager-plugin)

With gps-manager-plugin-dev package source files can be found in:

/usr/include/gps-manager-plugin/*.h 
/usr/lib/pkgconfig/gps-manager-plugin.pc

gps_manager_plugin_intf.h includes the API interfaces for the communication between the gps-manager and its GPS plugin.

typedef struct { 
/** Initialize plugin module and register callback function for event delivery */ 
int (*init) (gps_event_cb gps_event_cb, gps_server_param_t * gps_params); 
/** Deinitialize plugin module */ 
int (*deinit) (gps_failure_reason_t *reason_code); 
/** Request specific action to plugin module */ 
int (*request) (gps_action_t gps_action, void *data, gps_failure_reason_t *reason_code); 
} gps_plugin_interface; 
const gps_plugin_interface *get_gps_plugin_interface();

get_gps_plugin_interface() should be exported in GPS plugin. It gives gps_plugin_interface structure to the gps-manager, and the gps-manager will be communicated by these interfaces. When the gps-manager is started, the GPS plugin will be loaded and init() function is called. At this moment, A GPS device should be initialized. (Power control, firmware download etc.,)

int (*init) (gps_event_cb gps_event_cb, gps_server_param_t * gps_params);

When init() function is called, gps_event_cb is set. GPS events and data from a GPS device is delivered by registered call back function « gps_event_cb ».

typedef int (*gps_event_cb) (gps_event_info_t *gps_event_info);

GPS events are described in below.

typedef enum { 
GPS_EVENT_START_SESSION = 0x0000,/**< The session is started */ 
GPS_EVENT_STOP_SESSION, /**< The session is stopped */ 
GPS_EVENT_REPORT_POSITION = 0x0100,/**< Bring up GPS position data */ 
GPS_EVENT_REPORT_SATELLITE, /**< Bring up GPS SV data */ 
GPS_EVENT_REPORT_NMEA, /**< Bring up GPS NMEA data */ 
GPS_EVENT_SET_OPTION = 0x0200,/**< The option is set */ 
GPS_EVENT_GET_REF_LOCATION = 0x0300,/**< Get the reference location for AGPS */ 
GPS_EVENT_GET_IMSI, /**< Get IMSI for identification */ 
GPS_EVENT_OPEN_DATA_CONNECTION = 0x0400,/**< Request opening data network connection */ GPS_EVENT_CLOSE_DATA_CONNECTION, /**< Request closing data network connection */ 
GPS_EVENT_DNS_LOOKUP_IND, /**< Request resolving host name */ 
GPS_EVENT_AGPS_VERIFICATION_INDI, /**< Verification indicator for AGPS is required 
GPS_EVENT_FACTORY_TEST = 0x0500,/**< Factory test is done */ 
GPS_EVENT_ERR_CAUSE = 0xFFFF /**< Some error is occurred */ 
} gps_event_id_t; 

The GPS events will contain specific GPS event data which is part of gps_event_data_t and the GPS configuration is delivered by gps_server_param_t structure, refer to gps_manager_plugin_intf.h and gps_manager_extra_data_types.h. When the gps-manager want to make a request to GPS device, the request() function is called.

int (*request) (gps_action_t gps_action, void *data, gps_failure_reason_t *reason_code); 

Each request is classified by gps_action_t.

typedef enum { 
GPS_ACTION_SEND_PARAMS = 0x00, 
GPS_ACTION_START_SESSION, 
GPS_ACTION_STOP_SESSION, 
GPS_INDI_SUPL_VERIFICATION, 
GPS_INDI_SUPL_DNSQUERY, 
GPS_ACTION_START_FACTTEST, 
GPS_ACTION_STOP_FACTTEST, 
GPS_ACTION_REQUEST_SUPL_NI 
} gps_action_t;

With the standalone GPS (Unassisted GPS), GPS_ACTION_START_SESSION and GPS_ACTION_STOP_SESSION are mandatory actions. If the GPS_ACTION_START_SESSION is delivered, the GPS plugin shall start acquisition of satellites and report the GPS_EVENT_START_SESSION event to the gps-manager by the gps_event_cb callback function. Once the acquisitions completed and position is fixed, its position should be delivered by the gps_event_cb with the GPS_EVENT_REPORT_POSITION event id and the position data.

To shut down the gps-manager, deinitialize the GPS device with the gps-manager call deinit() function.

int (*deinit) (gps_failure_reason_t *reason_code);
  • New GPS Plugin Addition:
During the boot up gps-manager loads the gps plugin module. To load the plugin module it has to be defined in server.c file so that during the boot up, gps-manager loads the available plugin at /sys/devices/platform.

Ex:

#define PLATFORM_PATH 	"/sys/devices/platform“
#define PLUGIN_PATH	PLATFORM_PATH"/xxxxx_gps“

The function “check_plugin_module(char* module_name)” checks the access to available plugin at /sys/devices/platform and the “load_plugin_module” loads the plugin during the boot up time.

Configuration

None

References

None

Telephony


Introduction

Purpose of this document

This document is intended to provide a complete understanding of Tizen Telephony. It covers detailed Telephony Architecture including the various components of Telephony and workflow through Telephony framework. The document also provides Porting guidelines for vendors to ease development of OAL interface for their hardware.

Tizen Telephony features

  • Plug-in Architecture
  • Apache License version 2.0
  • Rich Telecommunication functionalities
  • CMUX support
  • Device ready


Definitions

  • Core Object

Bundle of functions and supportive database information designated to specific Module like; CALL, SS, SIM, Network, etc. which processing Requests/Responses/Notifications. Core Objects form the executable component of a Telephony Module (CALL, SS, SIM, Network, etc.).

  • Template Core Object

Bundle of functions designated to specific Module like; CALL, SS, SIM, Network, etc. which provide the interfaces to process Requests/Responses/Notifications based on the AP-CP interface mechanisms; for example AT-Commands based. Template Core Objects are non-executable components. Executable Core Objects are formed on cloning Template Core Objects.

  • HAL

HAL in other words Hardware Abstraction Layer, abstracts the actual Hardware used and ensures that similar functionality is provided by various hardware (modems) of the same modem vendor. All hardware specific changes are controlled and processed by HALs.

  • Hooks

Hooks provide a mechanism to tap Requests/Responses/Notifications of other Telephony Modules. Hooking is a transparent mechanism and doesn’t affect the normal processing of Requests/Responses/Notifications.



Tizen Telephony Architecture

Tizen Telephony supports plug-in Architecture which provides flexibility to include various types of predefined plug-ins into the system with very less changes.
01.png
Figure 1 provides Tizen Telephony Plug-in Architectural overview. Function calls across various plug-ins are through Tizen Telephony library (libtcore) APIs.

Telephony components

There 3 major components of Tizen Telephony:

Telephony libraries

Telephony provides 2 libraries

i. Telephony API (TAPI) library
- TAPI library (or simply TAPI) is a standardized interface provided to applications to interact with Tizen Telephony.
- It is provided as libtapi package.
- TAPI executes in application’s context, it provides Sync and Async APIs.
Telephony02.png


libtapi internal composition is depicted in Figure 2. Applications can interface to Telephony features like Call, SMS, Network, etc. through the respective module APIs exposed in libtapi.


ii. Core Telephony library (or libtcore)
Telephony03.png


Figure 3 provides the internal composition overview of libtcore.

- Core Telephony library (or libtcore) provides an API framework for Tizen Telephony to inter-work.
- It is provided as libtcore package.
- libtcore provides APIs for
o Creation/destruction/maintenance of various Server components like: Server, Communicator, HAL, Plug-in, Core Object, etc.
o Storage maintenance, Queue mechanism and general utility.
o CMUX support (creation/destruction/processing)
o AT parser

Telephony Plug-ins

There are 4 kinds of Plug-ins –

i. Communicator plug-ins
- Interfaces TAPI and Telephony Server.
- For example, DBUS communicator (DBUS_TAPI); it is provided by ‘default’.
Telephony04.png
ii. Modem plug-ins
- Core functional units providing Telephony functionality.
- Maintain and manage Telephony states.
- Maintain and manage Database related to Telephony.
Telephony05.png
iii. Modem Interface plug-ins
Telephony06.png
- Interfaces Telephony Server to Communication Processor.
- Hardware specific plug-ins which define hardware capabilities and usage.
- Modem Interface plug-in is also called as Hardware Abstraction layer (HAL).
iv. Free Style plug-ins
- Provide completely independent functionality irrespective of hardware (Communication processor).
- For example, plug-ins like packetservice, storage, indicator, etc.
Telephony07.png


Figure 8 provides an overview of all the Telephony Plug-ins together.

Telephony08.png

Telephony Server

- Tizen Telephony runs as a daemon also called as Telephony Server, the daemon is named as telephony-daemon.
- Telephony Server executes as g-main loop from glib library.

Telephony09.png



Porting OAL Interface

OEM vendors can port each and every available plug-in within Telephony as per their needs. It is not mandatory that all the plug-ins to be ported to support a specific hardware. This section provides guidance to OEM vendors to develop various Telephony plug-ins.

Implementation of a Plug-in

Any telephony plug-in is mandatorily required to provide a descriptor structure described below. Table 1: Plug-in descriptor

Structure Description(0-success, -1 - failure)
struct tcore_plugin_define_desc {
gchar *name;
enum tcore_plugin_priority priority;
int version;
gboolean (*load)();
gboolean (*init)(TcorePlugin *);
void (*unload)(TcorePlugin *);
};
Structure referred by Telephony Server to load, initialize, and unload the Plug-in.

This structure defines:

  1. Name of the Plug-in
  2. Initializing priority of the Plug-in
  3. Plug-in version
  4. Plug-in ‘load‘ function reference
  5. Plug-in ‘init‘ function reference
  6. Plug-in ‘unload‘ function reference

Descriptor structure of each plug-in should be named as ‘plugin_define_desc’. Server obtains the address of this symbol in order to provide control to the plug-in to execute its defined functionality.

Order of initialization of a plug-in among various other Telephony plug-ins is defined based on the plug-in’s ‘priority’.

OEMs need to specifically implement Modem and Modem Interface plug-in to support their hardwares. Sample implementations of Modem and Modem Interface plug-ins is available in Appendix section.




Configuration

There are no specific configurations required for Telephony except for conforming to the installation paths of various Telephony plug-ins as mentioned below.

All Telephony plug-ins need to be installed in the following folders –

  1. Modem Plug-ins – /usr/lib/telephony/plugins/modems/
  2. Other Plug-ins – /usr/lib/telephony/plugins/



Appendix

Sample implementation of Modem Interface plug-in

/* Structures for Power on and Rx mechanism */
struct custom_data {
 	int fd;
 	guint watch_id;
 	gboolean on;
};
 									 
static gboolean on_init(TcorePlugin *plugin)
{
 	TcoreHal *hal;
 	struct custom_data *data;
 	dbg("Init!!!");
 									 
 	/* Custom data for Modem Interface Plug-in */
 	dbg("Created custom data memory");
 									 
 	/* Create Physical HAL */
 	dbg("HAL [0x%x] created", hal);
 									 
 	/* Set HAL as Modem Interface Plug-in's User data */
 	tcore_plugin_link_user_data(plugin, hal);
 									 
 	/* Link Custom data to HAL's 'user_data' */
 	tcore_hal_link_user_data(hal, data);
 									 
 	/* Add callbacks for Send/Receive Hooks */
 	tcore_hal_add_send_hook(hal, _on_hal_send, NULL);
 	tcore_hal_add_recv_callback(hal, _on_hal_recv, NULL);
 	dbg("Added Send hook and Receive callback");
 									 
 	/* Set HAL state to Power OFF (FALSE) */
 	tcore_hal_set_power_state(hal, FALSE);
 	dbg("HAL Power State: Power OFF");
 									 
 	/* Resgister to Server */
 	tcore_server_register_modem(tcore_plugin_ref_server(plugin), plugin);
 									 
 	/* Check CP Power ON */
 	g_timeout_add_full(G_PRIORITY_HIGH,
 			 IMC_CP_POWER_ON_TIMEOUT, _power_on, hal, 0);
 	return TRUE;
}
 									 
static enum tcore_hook_return _on_hal_send(TcoreHal *hal,
 		unsigned int data_len, void *data, void *user_data)
{
 	msg("\n====== TX data DUMP ======\n");
 									 
 	return TCORE_HOOK_RETURN_CONTINUE;
}
 									 
static void _on_hal_recv(TcoreHal *hal,
 		unsigned int data_len, const void *data, void *user_data)
{
 	msg("\n====== RX data DUMP ======\n");
}
 									 
static gboolean _power_on(gpointer data)
{
 	struct custom_data *user_data;
 	TcoreHal *hal;
 	gboolean ret;
 	dbg("Entry");
 									 
 	/* Create and Open interface to CP */
 									 
 	/*
 	 *  If Creation or opening of interface to CP fails
 	 * Re-try for pre-defined maximum counts
 	 */
 									 
 	/* If maximum re-try counts expires notify Server */
 	tcore_server_send_notification(server, NULL,
 				TNOTI_SERVER_MODEM_ERR,
 				0, NULL);
 									 
 	/* Free HAL */
 	tcore_hal_free(hal);
 									 
 	return FALSE;
 									 
 	/*
 	 *  If Creation or opening of interface to CP is Successful
 	 *     1. Set HAL Power State
 	 *     2. Check for CP Power state and optional negotiate CMUX
 	 */
 	dbg("Created AP-CP interface");
 									 
 	/* Set HAL Power State ON (TRUE) */
 	tcore_hal_set_power_state(hal, TRUE);
 	dbg("HAL Power State: Power ON");
 									 
 	/* CP is ONLINE, send AT+CPAS */
}
 									 
static void on_unload(TcorePlugin *plugin)
{
 	TcoreHal *hal;
 	struct custom_data *user_data;
 	dbg("Unload!!!");
 									 
 	/* Unload Modem Plug-in */
 	tcore_server_unload_modem_plugin(tcore_plugin_ref_server(plugin), plugin);
 									 
 	/* Unregister Modem Interface Plug-in from Server */
 	tcore_server_unregister_modem(tcore_plugin_ref_server(plugin), plugin);
 	dbg("Unregistered from Server");
 									 
 	/* HAL cleanup */
 									 
 	/* Close CMUX and CMUX channels */
 	tcore_cmux_close(hal, _on_cmux_channel_close, NULL);
 	dbg("CMUX is closed");
 									 
 	/* Free HAL */
 	tcore_hal_free(hal);
 	dbg("Freed HAL");
 									 
 	/* Deinitialize the Physical Channel */
 	dbg("Deinitialized the Channel");
 									 
 	/* Free custom data */
 									 
 	dbg("Unloaded MODEM Interface Plug-in");
}
 									 
/* HAL Operations */
static struct tcore_hal_operations hal_ops = {
 	.power = NULL,
 	.send = _hal_send,
 	.setup_netif = _hal_setup_netif,
};
 									 
static TReturn _hal_send(TcoreHal *hal, unsigned int data_len, void *data)
{
 	/* Get HAL power state, if Powered ON 'write' data */
 									 
 	/* Write data to Device */
 									 
 	return TCORE_RETURN_SUCCESS;;
}
 									 
static TReturn _hal_setup_netif(CoreObject *co,
 			TcoreHalSetupNetifCallback func,
 			void *user_data, unsigned int cid,
 			gboolean enable)
{									 
 	if (enable == TRUE) {    /* Enable device */
 		dbg("ACTIVATE");
 									 
 		/* Open device to send IOCTL command */
 									 
 		/*
 		 * Send IOCTL to change the Channel to Data mode
 		 */
 									 
 		/* Update Device name */
 									 
 		/* Invoke callback function */
 		if (func)
 			func(co, ret, ifname, user_data);
 									 
 		return TCORE_RETURN_SUCCESS;
 	} else {    /* Disable device */
 		dbg("DEACTIVATE");
 		return TCORE_RETURN_SUCCESS;
 	}
}

Sample implementation of Modem plug-in

/* Initializer Table */
struct object_initializer init_table = {
 	.modem_init = s_modem_init,
 	.sim_init = s_sim_init,
 	.sat_init = s_sat_init,
 	.sap_init = s_sap_init,
 	.network_init = s_network_init,
 	.ps_init = s_ps_init,
 	.call_init = s_call_init,
 	.ss_init = s_ss_init,
 	.sms_init = s_sms_init,
 	.phonebook_init = s_phonebook_init,
 	.gps_init = s_gps_init,
};
 									 
/* Deinitializer Table */
struct object_deinitializer deinit_table = {
 	.modem_deinit = s_modem_exit,
 	.sim_deinit = s_sim_exit,
 	.sat_deinit = s_sat_exit,
 	.sap_deinit = s_sap_exit,
 	.network_deinit = s_network_exit,
 	.ps_deinit = s_ps_exit,
 	.call_deinit = s_call_exit,
 	.ss_deinit = s_ss_exit,
 	.sms_deinit = s_sms_exit,
 	.phonebook_deinit = s_phonebook_exit,
 	.gps_deinit = s_gps_exit,
};
 									 
static gboolean on_init(TcorePlugin *p)
{
 	dbg("Init!!!");
 									 
 	/* Initialize Modules (Core Objects) */
 	tcore_object_init_objects(p, &init_table);
 									 
 	/* Subscribe for the Events from CP */
 									 
 	dbg("Init - Successful");
 	return TRUE;
}
 									 
static void on_unload(TcorePlugin *p)
{
 	dbg("Unload!!!");
 									 
 	/* Deinitialize Modules (Core Objects) */
 	tcore_object_deinit_objects(p, &deinit_table);
}

List of libtcore APIs


at

void tcore_at_process_binary_data(TcoreAT *at,char *position,int data_len);
 									 
gboolean tcore_at_add_hook(TcoreHal *hal, void *hook_func);
TcoreAT *tcore_at_new(TcoreHal *hal);
void tcore_at_free(TcoreAT *at);
 									 
TReturn tcore_at_buf_write(TcoreAT *at, unsigned int data_len, const char *data);
 									 
TReturn tcore_at_set_request(TcoreAT *at, TcoreATRequest *req, gboolean send);
TcoreATRequest *tcore_at_get_request(TcoreAT *at);
TcoreATResponse *tcore_at_get_response(TcoreAT *at);
 									 
TReturn tcore_at_add_notification(TcoreAT *at, const char *prefix,
 			gboolean pdu, TcoreATNotificationCallback callback,
 			void *user_data);
TReturn tcore_at_remove_notification(TcoreAT *at, const char *prefix,
 			TcoreATNotificationCallback callback);
TReturn tcore_at_remove_notification_full(TcoreAT *at,
 			const char *prefix,
 			TcoreATNotificationCallback callback, void *user_data);
 									 
TcoreATRequest *tcore_at_request_new(const char *cmd, const char *prefix,
 			enum tcore_at_command_type type);
void tcore_at_request_free(TcoreATRequest *req);
 									 
gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data);
 									 
TcorePending *tcore_at_pending_new(CoreObject *co, const char *cmd,
 			const char *prefix, enum tcore_at_command_type type,
 			TcorePendingResponseCallback func, void *user_data);
 									 
GSList *tcore_at_tok_new(const char *line);
void tcore_at_tok_free(GSList *tokens);
char *tcore_at_tok_extract(const char *src);
char *tcore_at_tok_nth(GSList *tokens, unsigned int token_index);
 									 
TReturn tcore_prepare_and_send_at_request(CoreObject *co,
 			const char *at_cmd,
 			const char *at_cmd_prefix,
 			enum tcore_at_command_type at_cmd_type,
 			UserRequest *ur,
 			TcorePendingResponseCallback resp_cb,
 			void *resp_cb_data,
 			TcorePendingSendCallback send_cb,
 			void *send_cb_data);

communicator

Communicator *tcore_communicator_new(TcorePlugin *plugin, const char *name,
 			struct tcore_communitor_operations *ops);
void tcore_communicator_free();
 									 
TcorePlugin *tcore_communicator_ref_plugin(Communicator *comm);
const char *tcore_communicator_ref_name(Communicator *comm);
 									 
TReturn tcore_communicator_link_user_data(Communicator *comm, void *data);
void *tcore_communicator_ref_user_data(Communicator *comm);
 									 
TReturn tcore_communicator_send_response(Communicator *comm,
 			UserRequest *ur,  enum tcore_response_command command,
 			unsigned int data_len, const void *data);
 									 
TReturn tcore_communicator_send_notification(Communicator *comm,
 			CoreObject *source, enum tcore_notification_command command,
 			unsigned int data_len, const void *data);
 									 
TReturn tcore_communicator_dispatch_request(Communicator *comm, UserRequest *ur);

core_object

CoreObject *tcore_object_new(TcorePlugin *plugin, TcoreHal *hal);
void tcore_object_free(CoreObject *co);
 									 
TReturn tcore_object_set_free_hook(CoreObject *co, tcore_object_free_hook free_hook);
TReturn tcore_object_set_clone_hook(CoreObject *co, tcore_object_clone_hook clone_hook);
 									 
CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent);
CoreObject *tcore_object_clone_template_object(TcorePlugin *p, unsigned int co_type);
 									 
 									 
TReturn tcore_object_set_plugin(CoreObject *co, TcorePlugin *plugin);
TcorePlugin *tcore_object_ref_plugin(CoreObject *co);
 									 
TReturn tcore_object_link_object(CoreObject *co, void *object);
void *tcore_object_ref_object(CoreObject *co);
 									 
TReturn tcore_object_set_type(CoreObject *co, unsigned int type);
unsigned int tcore_object_get_type(CoreObject *co);
 									 
TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal);
TcoreHal *tcore_object_get_hal(CoreObject *co);
 									 
TReturn tcore_object_link_user_data(CoreObject *co, void *user_data);
void *tcore_object_ref_user_data(CoreObject *co);
 									 
TReturn tcore_object_set_dispatcher(CoreObject *co, tcore_object_dispatcher func);
TReturn tcore_object_dispatch_request(CoreObject *co, UserRequest *ur);
 									 
TReturn tcore_object_add_callback(CoreObject *co, const char *event,
 			 tcore_object_callback callback, void *user_data);
TReturn tcore_object_del_callback(CoreObject *co, const char *event, tcore_object_callback callback);
TReturn tcore_object_override_callback(CoreObject *co, const char *event, tcore_object_callback callback, void *user_data);
TReturn tcore_object_emit_callback(CoreObject *co, const char *event, const void *event_info);
 									 
void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl, unsigned int object_type, TcoreHal *hal);
 									 
void tcore_object_remove_mapping_tbl(void *mapping_tbl);
void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal);
void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl, unsigned int co_type);
 									 
 									 
void tcore_object_print_mapping_tbl(void *mapping_tbl);
 									 
TReturn tcore_object_init_objects(TcorePlugin *plugin, struct object_initializer *initializer_list);
 									 
void tcore_object_deinit_objects(TcorePlugin *plugin, struct object_deinitializer *deinitializer_list);

hal

TcoreHal *tcore_hal_new(TcorePlugin *plugin, const char *name,
 			struct tcore_hal_operations *hops,
 			enum tcore_hal_mode mode);
void tcore_hal_free(TcoreHal *hal);
 									 
TReturn tcore_hal_set_name(TcoreHal *hal, const char *name);
char *tcore_hal_get_name(TcoreHal *hal);
 									 
TcoreAT *tcore_hal_get_at(TcoreHal *hal);
enum tcore_hal_mode tcore_hal_get_mode(TcoreHal *hal);
TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode);
 									 
TReturn tcore_hal_set_power(TcoreHal *hal, gboolean flag);
 									 
TReturn tcore_hal_link_user_data(TcoreHal *hal, void *user_data);
void *tcore_hal_ref_user_data(TcoreHal *hal);
 									 
TReturn tcore_hal_send_data(TcoreHal *hal, unsigned int data_len, void *data);
TReturn tcore_hal_send_request(TcoreHal *hal, TcorePending *pending);
TReturn tcore_hal_send_force(TcoreHal *hal);
 									 
TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id,
 			unsigned int data_len, const void *data);
 									 
TReturn tcore_hal_add_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func, void *user_data);
TReturn tcore_hal_remove_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func);
TReturn tcore_hal_emit_recv_callback(TcoreHal *hal, unsigned int data_len, const void *data);
TReturn tcore_hal_add_send_hook(TcoreHal *hal, TcoreHalSendHook func, void *user_data);
TReturn tcore_hal_remove_send_hook(TcoreHal *hal, TcoreHalSendHook func);
 									 
TReturn tcore_hal_set_power_state(TcoreHal *hal, gboolean flag);
gboolean tcore_hal_get_power_state(TcoreHal *hal);
 									 
TcoreQueue *tcore_hal_ref_queue(TcoreHal *hal);
TcorePlugin *tcore_hal_ref_plugin(TcoreHal *hal);
 									 
TReturn tcore_hal_setup_netif(TcoreHal *hal, CoreObject *co,
 			TcoreHalSetupNetifCallback func,
 			void *user_data, unsigned int cid,
 			gboolean enable);

mux

TReturn tcore_cmux_init(TcoreHal *phy_hal, unsigned int frame_size,
 			TcorePendingResponseCallback resp_cb, void *resp_cb_data);
 									 
TReturn tcore_cmux_setup_internal_mux(tcore_cmux_mode mode,
 	int max_channels, unsigned int cmux_buf_size, TcoreHal *phy_hal,
 	cmux_setup_cb_func channel_setup_cb, gpointer channel_setup_user_data,
 	cmux_setup_complete_cb_func setup_complete_cb, gpointer setup_complete_user_data);
 									 
void tcore_cmux_close(TcoreHal *phy_hal,
 	cmux_channel_close_cb_func channel_close_cb, gpointer channel_close_user_data);
 									 
void tcore_cmux_rcv_from_hal(TcoreHal *hal, unsigned char *data, size_t length);

plugin

TcorePlugin *tcore_plugin_new(Server *server,
 			const struct tcore_plugin_define_desc *desc,
 			const char *filename, void *handle);
void tcore_plugin_free(TcorePlugin *plugin);
 									 
const struct tcore_plugin_define_desc *tcore_plugin_get_description(TcorePlugin *plugin);
 									 
char *tcore_plugin_get_filename(TcorePlugin *plugin);
char *tcore_plugin_ref_plugin_name(TcorePlugin *plugin);
Server *tcore_plugin_ref_server(TcorePlugin *plugin);
 									 
TReturn tcore_plugin_link_user_data(TcorePlugin *plugin, void *user_data);
void *tcore_plugin_ref_user_data(TcorePlugin *plugin);
 									 
TReturn tcore_plugin_add_core_object(TcorePlugin *plugin, CoreObject *co);
CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, unsigned int type);
GSList *tcore_plugin_get_core_objects_bytype(TcorePlugin *plugin, unsigned int type);
 									 
TReturn tcore_plugin_core_object_event_emit(TcorePlugin *plugin, 
 			const char *event, const void *event_info);
 									 
TReturn tcore_plugin_link_property(TcorePlugin *plugin, const char *key, void *data);
void *tcore_plugin_ref_property(TcorePlugin *plugin, const char *key);

queue

TcorePending *tcore_pending_new(CoreObject *co, unsigned int id);
void tcore_pending_free(TcorePending *pending);
 									 
unsigned int tcore_pending_get_id(TcorePending *pending);
TReturn tcore_pending_set_auto_free_status_after_sent(TcorePending *pending, gboolean flag);
gboolean tcore_pending_get_auto_free_status_after_sent(TcorePending *pending);
TReturn tcore_pending_set_request_data(TcorePending *pending, unsigned int data_len, void *data);
void *tcore_pending_ref_request_data(TcorePending *pending, unsigned int *data_len);
TReturn tcore_pending_set_timeout(TcorePending *pending, unsigned int timeout);
TcorePlugin *tcore_pending_ref_plugin(TcorePending *pending);
CoreObject *tcore_pending_ref_core_object(TcorePending *pending);
TReturn tcore_pending_set_priority(TcorePending *pending,
 			enum tcore_pending_priority priority);
TReturn tcore_pending_get_priority(TcorePending *pending,
 			enum tcore_pending_priority *result_priority);
TReturn tcore_pending_get_send_status(TcorePending *pending, gboolean *result_status);
TReturn tcore_pending_link_user_request(TcorePending *pending, UserRequest *ur);
UserRequest *tcore_pending_ref_user_request(TcorePending *pending);
 									 
TReturn tcore_pending_set_send_callback(TcorePending *pending,
 			TcorePendingSendCallback func, void *user_data);
TReturn tcore_pending_emit_send_callback(TcorePending *pending, int bytes);
 									 
TReturn tcore_pending_set_timeout_callback(TcorePending *pending,
 			TcorePendingTimeoutCallback func, void *user_data);
TReturn tcore_pending_emit_timeout_callback(TcorePending *pending);
 									 
TReturn tcore_pending_set_response_callback(TcorePending *pending,
 			TcorePendingResponseCallback func, void *user_data);
TReturn tcore_pending_emit_response_callback(TcorePending *pending,
 			int data_len, const void *data);
 									 
TcoreQueue *tcore_queue_new(TcoreHal *hal);
void tcore_queue_free(TcoreQueue *qeueu);
 									 
TReturn tcore_queue_push(TcoreQueue *queue, TcorePending *pending);
TcorePending *tcore_queue_pop(TcoreQueue *queue);
TcorePending *tcore_queue_pop_by_pending(TcoreQueue *queue, TcorePending *pending);
TcorePending *tcore_queue_pop_timeout_pending(TcoreQueue *queue);
TcorePending *tcore_queue_ref_head(TcoreQueue *queue);
TcorePending *tcore_queue_ref_tail(TcoreQueue *queue);
TcorePending *tcore_queue_pop_by_id(TcoreQueue *queue, unsigned int id);
TcorePending *tcore_queue_ref_pending_by_id(TcoreQueue *queue, unsigned int id);
TcorePending *tcore_queue_ref_next_pending(TcoreQueue *queue);
unsigned int tcore_queue_get_length(TcoreQueue *queue);
TcoreHal *tcore_queue_ref_hal(TcoreQueue *queue);
TReturn tcore_queue_cancel_pending_by_command(TcoreQueue *queue,
 			enum tcore_request_command command);
TcorePending *tcore_queue_search_by_command(TcoreQueue *queue,
 			enum tcore_request_command command, gboolean flag_sent);

server

Server *tcore_server_new();
void tcore_server_free(Server *s);
 									 
TReturn tcore_server_run(Server *s);
TReturn tcore_server_exit(Server *s);
 									 
TReturn tcore_server_add_plugin(Server *s, TcorePlugin *plugin);
GSList *tcore_server_ref_plugins(Server *s);
TcorePlugin *tcore_server_find_plugin(Server *s, const char *name);
 									 
TReturn tcore_server_add_communicator(Server *s, Communicator *comm);
GSList *tcore_server_ref_communicators(Server *s);
Communicator *tcore_server_find_communicator(Server *s, const char *name);
 									 
TReturn tcore_server_add_storage(Server *s, Storage *strg);
GSList *tcore_server_ref_storages(Server *s);
Storage * tcore_server_find_storage(Server *s, const char *name);
 									 
TReturn tcore_server_add_template_object(Server *s, CoreObject *template_co);
GSList *tcore_server_ref_template_object(Server *s);
CoreObject *tcore_server_find_template_object(Server *s, unsigned int type);
 									 
TReturn tcore_server_link_udev(Server *s, TcoreUdev *udev);
TcoreUdev *tcore_server_ref_udev(Server *s);
 									 
TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur);
TReturn tcore_server_send_notification(Server *s, CoreObject *source,
 			enum tcore_notification_command command,
 			unsigned int data_len, void *data);
 									 
TReturn tcore_server_add_request_hook(Server *s,
 			enum tcore_request_command command,
 			tcore_server_request_hook func, void *user_data);
TReturn tcore_server_remove_request_hook(Server *s,
 			tcore_server_request_hook func);
TReturn tcore_server_add_notification_hook(Server *s,
 			enum tcore_notification_command command,
 			tcore_server_notification_hook func, void *user_data);
TReturn tcore_server_remove_notification_hook(Server *s,
 			tcore_server_notification_hook func);
 									 
gboolean tcore_server_register_modem(Server *s, TcorePlugin *modem_iface_plugin);
void tcore_server_unregister_modem(Server *s, TcorePlugin *modem_iface_plugin);
gboolean tcore_server_update_modem_plugin(TcorePlugin *modem_iface_plugin,
 			TcorePlugin *modem_plugin);
GSList *tcore_server_get_cp_name_list(Server *s);
const char *tcore_server_get_cp_name_by_plugin(TcorePlugin *plugin);
 									 
gboolean tcore_server_add_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin,
 			unsigned int co_type, TcoreHal *hal);
void tcore_server_remove_cp_mapping_tbl(TcorePlugin *modem_iface_plugin);
void tcore_server_remove_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin, TcoreHal *hal);
void *tcore_server_get_cp_mapping_tbl(TcorePlugin *modem_plugin);
 									 
void tcore_server_print_modems(TcorePlugin *plugin);
 									 
TReturn tcore_server_load_modem_plugin(Server *s, TcorePlugin *modem_if_plugin,
 			const char *name);
void tcore_server_unload_modem_plugin(Server *s, TcorePlugin *modem_if_plugin);

storage

Storage *tcore_storage_new(TcorePlugin *plugin, const char *name, struct storage_operations *ops);
void  tcore_storage_free(Storage *strg);
const char *tcore_storage_ref_name(Storage *strg);
 									 
void *tcore_storage_create_handle(Storage *strg, const char *path);
gboolean tcore_storage_remove_handle(Storage *strg, void *handle);
 									 
gboolean tcore_storage_set_int(Storage *strg, enum tcore_storage_key key, int value);
int tcore_storage_get_int(Storage *strg, enum tcore_storage_key key);
 									 
gboolean tcore_storage_set_string(Storage *strg, enum tcore_storage_key key, const char *value);
char *tcore_storage_get_string(Storage *strg, enum tcore_storage_key key);
 									 
gboolean tcore_storage_set_bool(Storage *strg, enum tcore_storage_key key, gboolean value);
gboolean tcore_storage_get_bool(Storage *strg, enum tcore_storage_key key);
 									 
gboolean tcore_storage_set_key_callback(Storage *strg,
 	enum tcore_storage_key key, TcoreStorageKeyCallback cb, void *user_data);
gboolean     tcore_storage_remove_key_callback(Storage *strg,
 	enum tcore_storage_key key, TcoreStorageKeyCallback cb);
 									 
gboolean tcore_storage_update_query_database(Storage *strg, void *handle,
 	const char *query, GHashTable *in_param);
gboolean tcore_storage_read_query_database(Storage *strg, void *handle,
 	const char *query, GHashTable *in_param, GHashTable *out_param, int out_param_cnt);
gboolean tcore_storage_insert_query_database(Storage *strg, void *handle,
 	const char *query, GHashTable *in_param);
gboolean tcore_storage_remove_query_database(Storage *strg, void *handle,
 	const char *query, GHashTable *in_param);

udev

TcoreUdev *tcore_udev_new(Server *s, const gchar **subsystems);
void tcore_udev_free(TcoreUdev *udev);
 									 
Server *tcore_udev_ref_server(TcoreUdev *udev);
GUdevClient *tcore_udev_ref_client(TcoreUdev *udev);
GUdevEnumerator *tcore_udev_ref_enumerator(TcoreUdev *udev);
 									 
TReturn tcore_udev_add_enumerator_callback(TcoreUdev *udev, TcoreUdevEnumerCallback func,
 				void *user_data);
GList *tcore_udev_exec_enumerator(TcoreUdev *udev, gboolean event_emit_flag);
TReturn tcore_udev_add_callback(TcoreUdev *udev, const char *subsystem,
 				const char *action, TcoreUdevCallback func, void *user_data);
 									 
'''user_request'''
UserRequest *tcore_user_request_new(Communicator *comm, const char *modem_name);
void tcore_user_request_free(UserRequest *ur);
 									 
UserRequest *tcore_user_request_ref(UserRequest *ur);
void tcore_user_request_unref(UserRequest *ur);
 									 
TReturn tcore_user_request_set_free_hook(UserRequest *ur, UserRequestFreeHook free_hook);
TReturn tcore_user_request_set_response_hook(UserRequest *ur,
 			UserRequestResponseHook resp_hook, void *user_data);
 									 
Communicator *tcore_user_request_ref_communicator(UserRequest *ur);
char *tcore_user_request_get_modem_name(UserRequest *ur);
 									 
TReturn tcore_user_request_set_user_info(UserRequest *ur, const struct tcore_user_info *ui);
const struct tcore_user_info * tcore_user_request_ref_user_info(UserRequest *ur);
 									 
TReturn tcore_user_request_send_response(UserRequest *ur,
 			enum tcore_response_command command,
 			unsigned int data_len, const void *data);
 									 
TReturn tcore_user_request_set_command(UserRequest *ur,
 			enum tcore_request_command command);
enum tcore_request_command tcore_user_request_get_command(UserRequest *ur);
 									 
TReturn tcore_user_request_set_data(UserRequest *ur,
 			unsigned int data_len, const void *data);
const void *tcore_user_request_ref_data(UserRequest *ur, unsigned int *data_len);
 									 
TReturn tcore_user_request_set_metainfo(UserRequest *ur,
 			unsigned int metainfo_len, const void *metainfo);
const void *tcore_user_request_ref_metainfo(UserRequest *ur, unsigned int *metainfo_len);

util

TReturn tcore_util_netif(const char *name, gboolean enabled);
TReturn tcore_util_netif_set(const char *name, const char *ipaddr,
 		const char *gateway, const char *netmask);
 									 
char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip);
 									 
GHashTable *tcore_util_marshal_create();
void tcore_util_marshal_destory(GHashTable *ht);
 									 
GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string);
gchar *tcore_util_marshal_serialize(GHashTable *ht);
 									 
gboolean tcore_util_marshal_add_data(GHashTable *ht, const gchar *key,
 		const void *data, enum tcore_util_marshal_data_type type);
gboolean tcore_util_marshal_get_data(GHashTable *ht, const gchar *key,
 		void **data, enum tcore_util_marshal_data_type type);
 									 
gint tcore_util_marshal_get_int(GHashTable *ht, const gchar *key);
gchar *tcore_util_marshal_get_string(GHashTable *ht, const gchar *key);
GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key);
 									 
enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode);
 									 
unsigned char *tcore_util_decode_hex(const char *src, int len);
long tcore_util_encode_hex(const unsigned char *src, long num_bytes, char *buf);
 									 
int tcore_util_pdu_encode(const unsigned char *sca, const unsigned char *tpdu, int tpdu_len,
 		char *pdu);
unsigned char *tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len);
unsigned char *tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len);
char *tcore_util_convert_bcd2ascii(const char *src, int src_len, int max_len);
gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len,
 		unsigned char* src, int src_len);
gboolean tcore_util_convert_utf8_to_ucs2(unsigned char* dest, int* dest_len,
 		unsigned char* src, int src_len);
gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len, enum alphabet_format dcs, const unsigned char *src, unsigned short src_len);
		
void tcore_util_swap_byte_order(unsigned short* dest, const unsigned short* src, int src_len);
 									 
char *tcore_util_get_version(void);

Workflow

I. Initialization sequence
Telephony loading sequence (as shown in Figure 10) –
  1. Server loads Modem Interface plug-in
  2. Modem Interface plug-in registers to Server
  3. Server enumerates Modem Interface plug-in
  4. Create Physical HAL
  5. Modem Interface plug-in queries Modem State
  6. If Modem is ONLINE then, CMUX (internal) channels are established
  7. Logical HAL is created for each CMUX channel and assigned for a Core Object type, these are updated to mapping table.
  8. Change Physical HAL mode to TRANSPARENT (disables Queue)
  9. Modem Interface plug-in requests server to load Modem plug-in (corresponding to its Architecture)
  10. Server loads Modem plug-in
  11. Modem plug-in initializes sub-modules and creates Core Objects (based on the Core Object types defined in the mapping table by Modem Interface plug-in)
  12. Modem plug-in notifies Server of the event PLUGIN_ADDED
  13. Modem notifies Communicator of the event PLUGIN_ADDED
  14. Communicator creates interfaces for the Sub-modules present (based on the Core objects created)
Telephony10.png
II. Request processing sequence
Telephony Request processing sequence (as shown in Figure 11) –
  1. Application Request is sent to Communicator through TAPI
  2. Communicator creates User Request based on the incoming Request
  3. User Request is dispatch to Communicator
  4. Communicator dispatches User Request to Server
  5. Server finds the plug-in based on modem name
  6. Server extracts the Core Object type based on the Request command from plug-in’s Core Objects list
  7. Server dispatches User Request to Core Object
  8. Core Object dispatches User Request to dispatch function based on Request command
  9. Pending Request is formed, added to Queue and sent to Logical HAL assigned for the Core Object
  10. Logical HAL dispatches the Request data to a CMUX channel dedicated to it
  11. CMUX encodes the Request data and dispatches to Physical HAL
  12. Physical HAL sends the Request data to Modem
Telephony11.png
III. Response processing sequence
Telephony Response processing sequence (as shown in Figure 12) –
  1. Response data sent by Modem is received by Physical HAL
  2. Physical HAL dispatches the Response data to CMUX
  3. CMUX decodes the received Response data and dispatches the corresponding Logical HAL based on the CMUX channel
  4. Logical HAL dispatches the decoded Response data to the corresponding Core Object
  5. Core Object processes the received Response data and extracts the User Request from pending Queue and sends the Response data corresponding to User Request
  6. User Request extracts the Communicator
  7. Received Response data is sent to the corresponding Communicator
  8. Communicator sends the Response data to TAPI which communicates the Response to application
Telephony12.png
IV. Indication processing sequence
Telephony Indication processing sequence (as shown in Figure 13) –
  1. Notification data sent by Modem is received by Physical HAL
  2. Physical HAL dispatches the Notification data to CMUX
  3. CMUX decodes the received Notification data and dispatches the corresponding Logical HAL based on the CMUX channel registered for the Notification
  4. Logical HAL dispatches the decoded Notification data to the corresponding Core Object that registered for the Notification
  5. Core Object processes the received Notification data and dispatches to Server
  6. Server dispatches the Notification data to corresponding Communicator
  7. Communicator sends the Notification data to TAPI which communicates the same to application
Telephony13.png

Further References

[1] http://review.tizen.org/git/ - Tizen source website
[2] Telephony packages

framework/telephony/libtcore.git – Telephony Core Library
framework/telephony/libtapi.git – TAPI
framework/telephony/tel-plugin-dbus_tapi.git – Communicator (DBUS_TAPI)
framework/telephony/tel-plugin-at_standard.git – AT Standard plug-in
framework/telephony/tel-plugin-indicator.git – Free Style plug-in (Indicator)
framework/telephony/tel-plugin-packetservice.git – Free Style plug-in (packetservice)
framework/telephony/tel-plugin-vconf.git – Free Style plug-in (Database)
framework/telephony/tel-plugin-database.git – Free Style plug-in (VCONF)
framework/telephony/tel-plugin-imc.git – Modem plug-in (device)
framework/telephony/tel-plugin-imcmodem.git – Modem Interface plug-in (device)
framework/telephony/tel-plugin-atmodem.git – Modem plug-in (emulator)
framework/telephony/tel-plugin-vmodem.git – Modem Interface plug-in (emulator)

Application

Description

Tizen supports both core and reference applications. The core applications are developed with platform internal interfaces, such as Enlightenment Foundation Libraries (EFL) and other 3rd party libraries. The reference applications are developed with Tizen native APIs.

The following table shows whether the core and reference versions of the preloaded sample applications are supported by default on the Emulator and target device.

Application name Emulator Target
Core application Reference application Core application Reference application
Calculator No Yes Yes No
Calendar No Yes Yes No
CalendarService No Yes Yes No
Camera No Yes Yes No
Clock No Yes Yes No
Contacts No Yes Yes No
Email No Yes Yes No
Gallery No Yes Yes No
Home Yes No Yes No
ImageViewer No Yes Yes No
Internet No Yes No Yes
Lock Yes No Yes No
Memo No Yes Yes No
Messages No Yes Yes No
MusicPlayer No Yes Yes No
MyFiles No Yes Yes No
Phone No Yes Yes No
Settings No Yes Yes No
VideoPlayer No Yes Yes No

Configuration

You can switch a preloaded sample application between core and reference applications using the MIC image creator. To switch the application, remove the preloaded application package and add the new package image with the correct name. The following table shows the core and reference application image names of the preloaded sample applications.

Application Name Core Application Reference Application
Calculator org.tizen.calculator apps.Calculator
Calendar org.tizen.calendar apps.Calendar
CalendarService org.tizencalendar-service apps.CalendarService
Camera org.tizen.camera-app apps.Camera
Clock org.tizen.clock apps.Clock
Contacts org.tizen.contacts apps.Contacts
Email org.tizen.email apps.Email
Gallery org.tizen.gallery apps.Gallery
Home org.tizen.menu-screen apps.Home
ImageViewer org.tizen.image-viewer apps.ImageViewer
Internet org.tizen.browser apps.Internet
Lock org.tizen.lockscreen apps.Lock
Memo org.tizen.memo apps.Memo
Messages org.tizen.message apps.Messages
MusicPlayer org.tizen.music-player apps.MusicPlayer
MyFiles org.tizen.myfile apps.MyFiles
Phone org.tizen.call apps.Phone
Settings org.tizen.setting apps.Settings
VideoPlayer org.tizen.video-player apps.VideoPlayer

Appendix

NFC OAL API

Function Name Function Description Argument
net_nfc_oem_controller_init init; init the nfc chip net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_deinit deinit; deinit nfc chip none
net_nfc_oem_controller_register_listener register_listener; It registers callback function for tag event, se event, llcp event target_detection_listener_cb target_detection_listener : The callback function for tag event.

se_transaction_listener_cb se_transaction_listener : The callback function for se event. llcp_event_listener_cb llcp_event_listener : The callback function for llcp event net_nfc_error_e : When it fail, it returns error code.

net_nfc_oem_controller_unregister_listener unregister_listener; It releases callback function for tag event, se event, llcp event. none
net_nfc_oem_controller_check_firmware_version check_firmware_version; It checks the firmware version of nfc chip. net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_update_firmware update_firmeware; It tries to update firmware of nfc chip. net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_get_stack_information get_stack_information; It gets the list of support tag and current firmware version. net_nfc_stack_information_s : It’s pointer value to get The information of support tag and current firmware version.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_configure_discovery configure_discovery; It delivers the config information to discovery. net_nfc_discovery_mode_e : The mode to start/stop.

net_nfc_event_filter_e config : The information for tag filteing. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_get_secure_element_list get_secure_element_list; It gets the information of current secure element. net_nfc_secure_element_info_s: the pointer value to get secure element information.

int  : the pointer value to get the count of secure element. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_set_secure_element_mode set_secure_element_mode; It sets the secure element to use. net_nfc_secure_element_type_e : The information of secure element.

net_nfc_secure_element_mode_e : The mode information to set. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_connect connect; It tries to connect the detected tag/target. net_nfc_target_handle_s : The handle of tag/target for connecting.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_connect disconnect; It tries to disconnect the connected tag/target. net_nfc_target_handle_s : The handle of tag/target for disconnecting.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_check_ndef check_ndef; It checks the tag to support ndef or not. net_nfc_target_handle_s : The handle of the tag want to check ndef.

int  : The max size supported in tag. int  : The real data size saved in tag. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_check_target_presence check_presence; It checks the tag is exist in RF range. net_nfc_target_handle_s : The handle of tag to check presence.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_read_ndef read_ndef; It reads ndef data in tag. net_nfc_target_handle_s : The handle of tag to read.

data_s : The pointer value to save ndef data. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_write_ndef write_ndef; It writes the data to the tag. net_nfc_target_handle_s: The handle of tag to write.

data_s : The data to write. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_make_read_only_ndef make_read_only_ndef; It makes the tag to read only tag. net_nfc_target_handle_s: The handle of tag to make.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_transceive transceive; It sends/receives the low command to the Tag/target. net_nfc_target_handle_s: The handle of tag/target to transceive.

net_nfc_transceive_info_s: The pointer value included command/data to send and data to receive. data_s : The pointer value to send the information of context. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_format_ndef format_ndef; It formats the tag. net_nfc_target_handle_s: The handle of the tag to format.

data_s : The key value to send the tag for formatting. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_exception_handler exception_handler; When nfc-manager faces the unwanted exception, It tries to deinit and init the stack. Then it tries to unregister and register callback function. none
net_nfc_oem_controller_is_ready is_ready; It checks the status of the nfc stack. net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_llcp_config config_llcp; It sets the llcp configuration(miu, lto, wks, option). net_nfc_target_handle_s: The handle of the target to check llcp.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_check_llcp check_llcp_status; It sets the llcp configuration(miu, lto, wks, option). net_nfc_target_handle_s: The handle of the target to check llcp.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_activate_llcp activate_llcp; It activates to llcp function. net_nfc_target_handle_s: The handle of the target to activate.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_create_socket create_llcp_socket; It creates to llcp socket net_nfc_llcp_socket_t: The pointer value to receive the socket’s information.

net_nfc_socket_type_e socketType : The type of socket to create. uint16_t miu : The miu value. uint8_t rw : The rw value. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context.(It’s possible to set null)

net_nfc_oem_controller_llcp_bind bind_llcp_socket; It binds the socket. net_nfc_llcp_socket_t socket : The information about the socket to bind.

uint8_t service_access_point : The information of access point to bind. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_listen listen_llcp_socket; It makes the socket to listen. net_nfc_target_handle_s: The handle of the target.

uint8_t : The service name to listen. net_nfc_llcp_socket_t socket : The information of socket. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context.(It’s possible to set null)

net_nfc_oem_controller_llcp_accept accept_llcp_socket; It accepts the connect request in listen status. net_nfc_llcp_socket_t socket : Socket’s information to accept.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_connect_by_url connect_llcp_by_url; It tries to connect the server with service name. net_nfc_target_handle_s: The handle of the target to connect.

net_nfc_llcp_socket_t socket : Socket information to connect. uint8_t : service name to connect. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context. (It’s possible to set null)

net_nfc_oem_controller_llcp_connect connect_llcp; It tries to connect to the server with access point(port number). net_nfc_target_handle_s: The handle of target.

net_nfc_llcp_socket_t socket : The information of socket. uint8_t service_access_point : access point number net_nfc_error_e : When it fails, it returns error code. void: The value to control the context.(It’s possible to set null)

net_nfc_oem_controller_llcp_disconnect disconnect_llcp; It disconnect llcp link. net_nfc_target_handle_s: Socket information to disconnectnet_nfc_llcp_socket_t socket : The information of socket to disconnect.

net_nfc_error_e : When it fails, it returns error code. void: The value to control the context.(It’s possible to set null)

net_nfc_oem_controller_llcp_socket_close close_llcp_socket; It closes the llcp socket. net_nfc_llcp_socket_t socket : Socket information to close.

net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_recv recv_llcp; It receives the data using llcp link. net_nfc_target_handle_s: The handle of target to receive.

net_nfc_llcp_socket_t socket : Socket information to receive. data_s : The pointer value to receive the data. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context.(It’s possible to set null)

net_nfc_oem_controller_llcp_send send_llcp; It sends the data using llcp link. net_nfc_target_handle_s: The handle of target to send.

net_nfc_llcp_socket_t socket : The information of socket to send. data_s : The data to send. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context. (It’s possible to set null)

net_nfc_oem_controller_llcp_recv_from recv_from_llcp; It rejects the connect request from client socket. net_nfc_target_handle_s: The handle of target to reject.

net_nfc_llcp_socket_t socket : The information of socket to reject. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_send_to send_to_llcp; It sends the data using service access point. net_nfc_target_handle_s: The handle of peer target.

net_nfc_llcp_socket_t socket : The information of socket. data_s : The data to send. uint8_t service_access_point : service access point to send. net_nfc_error_e : When it fails, it returns error code. void: The value to control the context. (It’s possible to set null)

net_nfc_oem_controller_llcp_reject reject_llcp; It rejects the connect request from client socket. net_nfc_target_handle_s: The handle of target to reject.

net_nfc_llcp_socket_t socket : The information of socket to reject. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_get_remote_config get_remote_config; It gets llcp socket config information of peer device’s. net_nfc_target_handle_s: The handle of peer target.

net_nfc_llcp_config_info_s: The pointer value to get config information of peer device's llcp socket. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_llcp_get_remote_socket_info get_remote_socket_info; It gets llcp socket information of peer device’s. net_nfc_target_handle_s: The handle of peer target.

net_nfc_llcp_socket_t socket : The information of llcp socket. net_nfc_llcp_socket_option_s : The pointer value to save the information of remote socket. net_nfc_error_e : When it fails, it returns error code.

net_nfc_oem_controller_sim_test sim_test; It tests SWP link with SIM and NFC chipset. net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_test_mode_on test_mode_on; It changes The nfc chipto test mode. (test mode is exist only NXP case. If there are none, it doesn’t need to implemented.) net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_test_mode_off test_mode_off; It changes the status of nfc chip from test mode to normal mode.

(Test mode is exist only NXP case. If there are none, It doesn’t need to implemented.)

net_nfc_error_e : When it fails, it returns error code.
net_nfc_oem_controller_support_nfc support_nfc It check each chip’s device file. NET_NFC_NOT_SUPPORTED : If it can’t find the device file, it return NET_NFC_NOT_SUPPORTED
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox