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 smartphones and tablet devices, though more device types will be available 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 necessary tools, and the development environment setup, as well as creating a Tizen Image and demonstrating the modifications needed across various functional areas.

Tizen Architecture

The following 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 predefined 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 notifications.

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. Email supports 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 the platform security enablers, such as access control, certificate management, and secure application distribution.

For more information, see Security/Tizen 3.0 security porting guide and All 3.X security pages.

System

System consists of service (process), 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 and low memory management
  • Service management, such as watchdog management and capability control

Telephony

Telephony consists of cellular functionalities communicating with the modem:

  • Provides call services (single call and multiparty call).
  • Provides call-related and non-call-related supplementary services (call waiting, barring, and 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 runtime for Web applications.

Development Environment Setup

To set up the Tizen OS development environment and to obtain information regarding development, see Setup your environment and Installing development tools.

Getting Source Code&Build

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

  • git clone
  1. Download the xml file and extract each <git_path>.
  2. Clone each git project using the git clone ssh://<Username>@review.tizen.org:29418/<git_path> command.
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
  1. Initialize the repository using the repo init -u ssh://<Username>@review.tizen.org:29418/scm/manifest -b <branch_name> -m <profile>.xml command.
  2. Replace the project's .xml file inside the $workspace/.repo/ directory with the manifest file in the $srcrpm_snapshot.
  3. Use the repo sync to sync the repository.
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 the repo sync command, first of all check whether the git project name inside the projects.xml file exists in review.tizen.org.

For more information, see Cloning the Tizen source.

See the following links 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

Kernel Build

To build the Tizen kernel for the TM1 board:

  1. Install and setup cross compile tools on your system if the target and host are different (such as x86).
    You can use the Linaro toolchain binaries or the Ubuntu package of them and have your environment setup for the cross tools (such as export CROSS_COMPILE=....).
  2. Prepare the 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
  3. If your kernel source has been used to create binaries for other architecture, start by cleaning them up.
    $ make distclean
  4. Setup the .config file for TM1.
    $ make ARCH=arm tizen_tm1_defconfig
  5. After reconfiguring your needs (such as make ARCH=arm menuconfig) or using the stock configuration (no modifications), build it.
    $ make ARCH=arm zImage
    $ make ARCH=arm dtbs
  6. 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
  7. 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
  8. Make a .tar archive from dzImage and modules.img.
    You can make your own .tar file from the 2 files.
    $ tar cf FILENAME_YOU_WANT.tar -C arch/arm/boot dzImage -C ../../../usr/tmp-mod modules.img
  9. Send the .tar image to the target using lthor.
    $ lthor FILENAME_YOU_WANT.tar

Image Build

Tizen Bootup Overview

This section provides a brief overview of the typical booting sequence, starting from the 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. Just make sure that the correct machine ID and the boot arguments are passed from the boot loader.

Platform Bootup

After mounting the initial RAM disk image, initramfs hands over the control to systemd as system manager daemon in the 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 (/etc/fstab).


The following figure shows the early boot sequence after starting the 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</code.
    • At this point, most of file systems like <code>/opt, /tmp, and /media are mounted and the 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 (such as vconf-setup and tizen-debug-level) also are executed.


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


The following figure shows 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 (such as systemd-logind) are also started in this phase.


  • graphical.target
    • Special target unit for setting up a graphical environment.
    • Some important daemons (such as access control server and OMA DS agent server) that must have root permission are launched at this point.
    • Tizen platform uses the 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 and mobile service: tizen-middleware.target starts the platform service daemons, such as calendar, contacts, email, message, sound, and download provider. tizen-mobile-session.target starts some service daemons related with the mobile session.

BSP Customization

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


Boot Loader 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 device tree binary for the device to RAM. For the Tizen platform, the boot loader comes in 2 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, you can skip this section and move directly to the kernel section.

Boot Loader Setup and Build

To build the Tizen TM1 boot loader:

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

Be careful when you modify the boot loader, as there is a risk of breaking the device for good.

Boot Loader 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. In this case, the kernel refers to the open source Linux kernel that is customized for the Tizen platform. The following section gives 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 is a uImage that is suitable only for a u-boot boot loader. If you have chosen a secure booting configuration in your boot loader, this uImage must be compatible with your boot loader.


Kernel Configurations

To download the Tizen kernel source package, see Getting Source Code and Build. 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, see Kernel Build.

Note
Tizen uses INOTIFY instead of DNOTIFY. You must 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 (such as ext2, jfs, and ext4). The VFS provides a switching layer between the SCI (system call interface) and the file systems supported by the kernel, as shown in the following figure.

Filesystem.png

At the top of the VFS is a common API abstraction of functions, such as open, close, read, and write. 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 the /boot directory of rootfs. Here s-boot, u-boot, and the kernel image are saved as a file format, provided as system.tar.

  1. The CSA (Configuration Saved Area) partition is for non-volatile data, such as the calibration value of modem.
  2. The boot partition includes the 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 canbe provided as a platform.img file.
  5. The data partition is mounted in the /opt directory and it includes applications, libraries of applications, and the platform database. It can be provided as a data.img file.
  6. The CSC (Customer Software Configuration) partition is mounted in the /mnt/csc directory. It can store the customer’s software configuration, such as the default language and time zone.
  7. The UMS (USB Mass Storage) partition is mounted in the /opt/media directory and it includes default (media) contents. It can be provided as ums.img.
  8. Each image file, platform.img, data.img, and ums.img can be zipped for downloading, for example, <IMAGE_NAME>.tar.gz.

File System Hierarchy Standard in Tizen

Each partition has the hierarchy illustrated in the following figure.

Filesystemhierarchy.png

Supported File Systems in Tizen

Tizen supports the Extended 4 (ext4) 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 4 (ext4) file system is configured as a default file system for Tizen.

Configuration

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

Reference

These are the configuration options to be enabled in the kernel configuration file.

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


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 must be provided at the boot loader.

Mmc.png

MSHCI/SDHCI Features Overview

The MMC/SD/SDIO driver supports the following 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 the kernel is located at /driver/mmc.

MMC subsystem structure is divided into 3 parts:

  • MMC block device driver located at /driver/mmc/card/
  • Protocol stack for MMC, SD, SDIO located at /driver/mmc/core/
  • Host controller driver located at /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

The SDHCI controller is supported in the MMC/SD/SDIO interface. The Mobile Storage Host controller is only supported in 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

The X denotes the MMC partition number. Details of the partition mount point for Tizen are covered under Tizen Partition Layout.

System

systemd

As a system and service manager for Tizen system, systemd (ver. 43), is newly applied to platform. It is a replacement for the System V init daemon. Basically, systemd provides a lot of functionality such as parallelized 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.

The following figure shows the systemd architecture.

Systemd arch.PNG

systemd Utility

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

systemd Target

Tizen boot-up process is split up in various discrete steps. Each step is grouped to its unit using a target unit to synchronize the point. The boot-up process is highly parallelized in each target, which means that the order in which the specific target units are reached is not deterministic.

systemd Daemon

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

systemd Core

The systemd core part manages all units, such as service, socket, and mount, and stores all log data. The systemd core is controlled by using a systemd utility, such as systemctl.

systemd Library & Linux Kernel

systemd requires that the cgroup and autofs options are enabled in the Linux Kernel configuration. It also depends on dbus and some libraries, such as libnotify and libudev.

System Framework

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

Systemframework.png

The following subsections introduce the System framework sub-components.

System Server

The system server handles system events, such as memory status, battery level, and plug and play device status, as well as 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 wake-up 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 the display backlight dimming/off and device 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 display must not be dimmed or switched off. The applications can request that the Power manager does not change the display to a specific state.

Conditional State Transition

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

Unlock: Allow system to enter lower state than specific state

You have the following options to control the device’s power status and sleep mode.

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

Device Manager

The device manager provides the following features:

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

USB manager

With the USB manager, you can:

  • Set USB configurations to connect to the PC
  • Monitor external USB host devices, such as keyboards, mice, cameras, USB storages, and USB printers
  • Monitor 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 or 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 must implement the API defined in the devman_plugin_intf.h header file and compile their library as a libslp_devman_plugin.so file. OEM APIs can be grouped as power, battery, haptics, LED, light, and memory. On initialization, the Device Manager (devman) calls the OEM_sys_get_devman_plugin_interface() function, which in turn returns the address of implemented OEM APIs. When applications request the device manager APIs, the appropriate OEM APIs referred by the OEM_sys_devman_plugin_interface() function are be called.

The 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 the /usr/lib directory.

The 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: 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();

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

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;
}

The following example shows the implementation code for the OEM_sys_get_backlight_brightness() function. This function gets the current brightness of the backlight unit and the output is stored in the value variable. The value can range from 0 <= value <= MAX_BACKLIGHT_BRIGHTNESS.

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

#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 sys_get_int() function provides access to the kernel device driver node parameters. The path parameter is defined in the devman_define_node_path.h header file, as described above. The value to get or set is stored in the value parameter. In similar ways , functions, such as sys_get_str(), sys_set_int(), sys_set_str(), and sys_get_node() are implemented to set or get the parameter values at the respective path. The following example shows the implementation for the 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 power states are defined in the following enumeration.

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 the maximum CPU frequency value in KHz. Optional
int (*OEM_sys_get_cpufreq_cpuinfo_min_freq) (int *value); The function gets the limitation of the minimum CPU frequency value in KHz. Optional
int (*OEM_sys_get_cpufreq_scaling_max_freq) (int *value); The function gets the current maximum CPU frequency in KHz.

(CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ)

Optional
int (*OEM_sys_set_cpufreq_scaling_max_freq) (int value); The function sets the current maximum CPU frequency in KHz.

(CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ)

Optional
int (*OEM_sys_get_cpufreq_scaling_min_freq) (int *value); The function gets the current minimum CPU frequency in KHz.

(CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ)

Optional
int (*OEM_sys_set_cpufreq_scaling_min_freq) (int value); The function sets the current minimum CPU frequency in KHz.

(CPUINFO_MIN_FREQ <= value <= CPUINFO_MAX_FREQ)

Optional
int (*OEM_sys_get_uart_path) (int *value); The function gets the current path of the uart node.

(0: CP, 1: AP)

Optional
int (*OEM_sys_set_uart_path) (int value); The function sets the current path of the uart node.

(0: CP, 1: AP)

Optional
int (*OEM_sys_get_usb_path) (int *value); The function gets the current path of the USB node.

(0: CP, 1: AP)

Optional
int (*OEM_sys_set_usb_path) (int value); The function sets the current path of the 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 the 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 maximum 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 (milliseconds). 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 image enhance algorithm mode.

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

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

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

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

(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 image enhance algorithm scenario.

(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 image enhance algorithm tone.

(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 image enhance algorithm tone.

(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 mode of the 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 the Image Quality Enhancement Algorithm is supported. Optional
int (*OEM_sys_set_display_frame_rate) (int value); The function sets the frame rate of the LCD display.

(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 maximum brightness of backlight unit. Mandatory
int (*OEM_sys_get_backlight_min_brightness) (int index, int *value); The function gets the minimum 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 use standard input driver methods. These interfaces are used to get the key and touch events. The following example shows the standard input structure in the include/linux/input.h header file.

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 fully charged status.

(0: Not fully charge, 1: Fully charged)

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

CPU DVFS 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, such as performance, powersave, userspace, and ondemand, 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 the following configuration:

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

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

To support dynamic CPU hotplug to reduce power consumption, select the following 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

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:

Sensorframework.png

  • Accelerometer Sensor
The accelerometer sensor is used to measure the acceleration of the device. The 3-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 3 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 the 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 must 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.

Plugin Types in the Sensor Framework

Sensor plugins takes care of interacting with the sensor driver. Plug-ins process data from sensor drivers and communicate it to the sensor server. The framework has the following types of sensor plugins:

  • 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 the common sensor plugin (processor, filter, sensor) code in git:sensor-framework/sensor-plugin-source.

Processor Plugin

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

The following code snippet shows the prototype implementation of the 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, initializes all private variables. NA
virtual ~ accel_processor() Destructor, deallocates variables. NA
const char *name(void) Returns the plugin's name. Returns m_name (processor plugin name)
int id(void) Returns the plugin's ID. Returns m_id (processor plugin ID)
int version(void) Returns the plugin's version. Returns m_version (processor plugin version)
bool update_name(char *name) Updates the sensor_name. The parameter is the new processor plugin name. Returns true on success.
bool update_id(int id) Updates the ID of the plugin. The parameter is the new plugin ID. Returns true on success.
bool update_version(int version) Updates the version of the plugin. The parameter is the new plugin version. Returns true on success.
bool add_input(csensor_module * sensor) Adds a sensor module in the processor plugin. The parameter is the sensor plugin's module. Returns true on success.
bool add_input(cfilter_module * filter) Adds a filter module in the processor plugin. The parameter is the filter plugin's module. Returns true on success.
long value(int id) Gets the sensor data by port ID. The parameter is the port ID. Returns the sensor data by the port ID.
long value(char *port) Gets the sensor data by the port name. The parameter is the port name. Returns the sensor data by the port name.
cprocessor_module *create_new(void) Creates a list of processors and returns the processor module. Returns the processor module instance on success.
void destroy(cprocessor_module * module) Deletes a module in the list of processors. Returns the processor module instance on success.
static void *working(void *inst) Gets sensor data and makes event, sets the event to vconf. The parameter is the processor module. NA
static void *stopped(void *inst) Stops the loop. The parameter is the processor module. NA
virtual bool start(void) Starts the processor plugin (set the m_client for counting) . Returns true on success.
virtual bool stop(void) Stops the processor plugin (set m_client for counting). Returns true on success.
bool add_callback_func(cmd_reg_t * param) Registers the callback event. The parameter is the event parameter. Returns true on success.
bool remove_callback_func(cmd_reg_t * param) Unregisters the callback event. The parameter is the event parameter. Returns true on success.
bool check_callback_event(cmd_reg_t * param) Checks the callback event. The parameter is the event parameter. Returns true on success.
long set_cmd(int type, int property, long input_value) Sets the event or data in a sensor and returns the result or output data. The parameters are the sensor type, property or command for the sensor, and input data for the property or command. Returns output data from property or command.
int get_property(unsigned int property_level, void *property_data) Returns the sensor specification. The parameters are the desired specification and the specification data. Returns 0 on success, and a negative value on failure.
int get_struct_value(unsigned int struct_type, void *struct_values) Returns meaningful sensor data. The parameters are the desired data type and the meaningful data structure, including values. Returns 0 on success, and a negative value on failure.
cmodule *module_init(void *win, void *egl) Initializes and creates the module. Returns the created module on success, otherwise NULL.
void module_exit(cmodule *inst) Deletes the created module. NA

The following code snippets shows the 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.

The following code snippet shows the prototype implementation of the 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 to be read from the sensor node, then return that status. This function waits during polling time and calls the update_value. If the wait is true, then wait during the polling interval time.
int port_count(void) Returns the port count in the sensor. For example, accelerometer sensor has X, Y, Z port. In this case, the port_count function returns 3.
const char *port(int idx) Returns the port name by the index number. When the port(0) called in the accelerometer sensor, then this function returns ‘x’.
void reset(void) Resets the sensor node.
bool start(void) / bool stop(void) Enables or disables the sensor. This 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) Announces that sensor’s data reading type is polling or interrupted. If it is true, it is polling, otherwise it is interrupted.
long polling_interval(void) Senses the need to poll data. 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.

The following code snippet shows the sensor plugin code for the 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.

The following code snippet shows the prototype implementation of the 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

The Sensor Framework loads the sf_sensor.conf, sf_filter.conf, sf_processor.conf, sf_datastream.conf configuration files for loading sensor, filter, and processor plugins. All configuration files are included in the 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, the ID and version are updated to the following ID and 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 configuration file:
[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 do not need to edit the datastream configure file.

Reference

Reference kernel configuration for sensors varies 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

The following figure shows an overview of the Tizen UI and graphics architecture.

Graphicsarchitecture.png


Tizen provides high performance 3D graphics as a component of UI and graphics. 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 to 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. Embedded system-specific features were added to enhance rendering efficiency, such as precision qualifiers to the shading language from OpenGL ES 2.0.

OpenGL

The following figure shows an overview of the interface for Tizen high performance 3D graphics library with OpenGL.

Opengl.png

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.

3D Graphics Components

OpenGL ES 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. It accepts primitives, such as points, lines, and triangles, and converts them into pixels using a graphics pipeline, known as the OpenGL state machine.

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. The EGL interface has the following components:

  • EGLDisplay (X Display): Encapsulates all of the system dependencies for interfacing with the native windowing system.
  • EGLSurface: Encapsulates the rendering destinations (window surface, pixmap surface), which are tied to X Window and X Pixmap.
  • EGLContext: Encapsulates the OpenGL ES rendering context, which holds the state of GL server and client.

The following figure shows 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, as the common 3D applications use DRI2 based EGL and the 3D composite window manager usually needs a DRI2 based EGL.
FBDEV based EGL (optional)
  • The FBDEV must consist of a triple buffer.
  • It must be performed with page flipping instead of copying the buffer.
  • To avoid a tearing problem, perform with LCD vsync signal. Usually, the compositor enables vsync using the eglSwapInterval() API.
DRI2 based EGL (mandatory)
  • DRI2 based EGL must be performed with the X11 DRI2 protocol.
  • It must support texture from pixmap (using the EGL_KHR_image_pixmap and GL_OES_EGL_image).
GPU synchronization API
  • To avoid flickering, use an internal EGL API, which is used to wait for completion of the buffer copy command.
Limitation of the EGL surface
  • The FBDEV must 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
Note
A method to allow the CPU to read and write the texture memory area of the GPU is needed.
Header and library name

The header files and libraries must 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

The X server is an X Window system display server that provides a basis for the 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 shows the relations between the X Window system and input drivers.

Input.png

X Window system

The X Window system provides the interface for the manipulation of resources, such as windows, pixmap, and gc. 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 the X server encounters something that the X client may be interested in, such as configure or exposure events.

X server

The X server reads events from the internal event queue and makes and sends the X events to the X clients.

X input driver

X input driver reads the input event stream from each input device node, makes X internal events, and put the events into the X server's internal event queue. For doing this, the X input driver mainly uses the interfaces implemented on the xf86 DDX layer inside X server.

evdev driver

Implements for reading the input event stream originated from kernel evdev subsystem and for creating X internal events. Supports devices, such as keyboard, mouse, touchpad, and touch screen.

evdev multi-touch driver

Implements for reading the MT protocol event stream originated from kernel evdev subsystem, for interpreting them and for creating X internal events. Supports touch screen devices.

Porting OAL Interface

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

Evdev module

The evdev contains the following 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 depends on the X server's configuration.

  • After the device setup is done, the device reads input events from the device node, creates internal events, and puts them in the input event queue inside X server.
  • To use the X input driver, the module must be loaded and must be registered as an input driver by the X server.
  • Module, driver, and device must provide the following information:
    • Module: module information.
    • Driver: driver information.
    • Device: read() for reading input events, proc() for controlling the device status.
For information about the data structures and functions for each module and device, see http://www.x.org/wiki/Development/Documentation/XorgInputHOWTO.
The basic module information is stored inside XF86ModuleData (xf86Module.h) and is provided to the X server.

Configuration

ServerFlags
  • AllowEmptyInput
true means that X server is started without any keyboard or mouse driver.
  • AutoAddDevices
false means that hot plugged input devices are not supported.
  • AutoEnableDevices
true means that the DevicePresenceNotify event is sent to all X clients by default.
InputClass
  • Identifier
Sets the unique input device name.
  • Driver
Sets the driver for device.
  • MatchDevicePath
Sets the device node path to be handled by the device. A wildcard can be used.
  • Option
Sets known options and custom options to be used inside driver for setting up devices or for enabling or disabling certain feature. Integer, Boolean, and string type can be used.
  • Checks that the found device matches one of device types (MatchIsTouchScreen, MatchIsTablet, MatchIsPointer, MatchIsKeyboard) and sets the type for the device if matched.
Tizen Extension for Evdev Multi-touch Driver
  • Provides 1 legacy single touch protocol
  • Provides 2 kinds of MT protocol:
    • MT protocol A (which includes Tracking ID)
    • MT protocol B
  • To implement support for a new touch protocol:
    • Implement a new touch protocol inside the driver.
    • Clone the evdev multi-touch driver and implement a new touch protocol inside the driver.
    • Convert from a new protocol to an existing protocol, which is supported by the evdev multi-touch driver.

Video Driver

The following figure illustrates the X server and the X video driver.

Video.png

X Window System

X Window system provides the interface for the manipulation of resources, such as windows, pixmap, and gc. The X clients send the requests to 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 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 the xf86 DDX layer to display something on a screen.

  • Driver Module:
Implementation of a driver module for xf86 DDX.
  • Mode Setting:
Implements the devices to display images on it.
  • EXA:
Implements Graphic acceleration Architecture. Handles memory allocation and exa draw primitives.
  • DRI2:
Implements the 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 drawable mode. By default, the extension reports no video adapters 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 must implement the following driver module and extensions, using the interface provided by the 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 in the modnameModuleData format, where <modname> is the name of the X video driver.

The following example defines the XF86ModuleData of the sec_drv.so driver:

_X_EXPORT XF86ModuleData secModuleData = {&SECVersRec, SECSetup, NULL};

For xf86 header information, see 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, see http://www.x.org/releases/X11R7.6/doc/xorg-server/DESIGN.txt.

ScrnInfoPtr
  • The data structure must 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 the ScrnInfoPtr structure are set up by the function pointers of ScrnInfoPtr.
  • The ScrnInfoPtr structure has the following function pointers:
xf86ProbeProc *Probe
xf86PreInitProc *PreInit
xf86ScreenInitProc *ScreenInit
xf86SwitchModeProc *SwitchMode
xf86AdjustFrameProc *AdjustFrame
xf86EnterVTProc *EnterVT
xf86LeaveVTProc *LeaveVT
xf86ValidModeProc *ValidMode

For detailed header information, see 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, xf86CrtcConfigFuncsRec *funcs, have to be set in the X video driver.
    • The function pointers of the xf86CrtcConfigFuncsRec are:
Bool (*resize)(ScrnInfoPtr scrn, int width, int height);

For detailed header information, see 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, xf86CrtcFuncsRec *funcs, have to be set in the X video driver.
    • The function pointers of the 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);

For detailed header information, see 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 output information.
    • The X video driver creates the number of instances of outputs as the number of hardware connectors.
    • The function pointers, xf86OutputFuncsRec *funcs, have to be set in the X video driver.
    • The function pointers of the 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);

For detailed header information, see 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 the 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 the 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);

For detailed header information, see 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 structure manages and controls the DRI2 buffers.
    • It contains the function pointers and the variables to be implemented by the X video driver.
    • The function pointers and variables of the 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;

For detailed header information, see 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 1 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 reports video adaptors as per the availability, provided the data in their respective XF86VideoAdaptorRecs was valid. The xf86XVScreenInit() function copies data from the structure passed to it, so that the driver can free it after the initialization. At the moment, the DDX supports only rendering into window drawables. Pixmap rendering is supported after a sufficient survey of suitable hardware is completed. For more information, see 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 the 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)

For detailed header information, see http://source.tizen.org/git/?p=pkgs/xorg/server/xorg-server.git;a=blob;f=hw/xfree86/common/xf86xv.h.

References

OpenGL ES 1.X, 2.0 and EGL 1.4 API specifications are supported by Tizen. OpenGL ES and EGL APIs are managed by the Khronos group. For more information about OpenGL ES API and prototype, see the Khronos website.

For information about the Xorg Input driver, see http://www.x.org/wiki/Development/Documentation/XorgInputHOWTO.

For the Khronos API Implementers Guide, see http://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 the input device
CONFIG_INPUT_EVDEV For the evdev input system
CONFIG_INPUT_UINPUT For enabling input emulation
CONFIG_INPUT_TOUCHSCREEN For enabling the touch screen
CONFIG_INPUT_KEYBOARD For enabling keyboard devices such as gpio-key and touch-key
CONFIG_KEYBOARD_GPIO For gpio-key
CONFIG_INPUT_MOUSEDEV

CONFIG_INPUT_MOUSE_PSAUX

For mouse devices

Multimedia

Camera

The Multimedia camcorder framework controls the GStreamer camera plugin to capture camera data from the device. The kernel interfaces to control the camera device can be different for different chipsets, so the camera HAL (Hardware Abstraction Layer) used by camera plugin is provided and it must be implemented specifically for each chipset. Each configuration file contains its own specific hardware dependent information. The Multimedia Camcorder framework reads and parses the information in these configuration 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.

Configuration Files

There are 3 config files for the Multimedia Camcorder framework. They are 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. 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

The default reference camera source plugin which uses the camera HAL interface is provided.

Camera HAL

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

  • Repository path: platform/core/multimedia/mm-hal-interface
  • File name: tizen-camera.h
Major Functions

The following table lists the functions related to initialization and deinitialization.

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

The following table lists the functions related to open and close camera device.

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

The following table lists the functions related to getting device information.

Prototype Description
int camera_get_device_list(void *camera_handle, camera_device_list_t *device_list) Gets the camera device list.
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 the camera HAL.
int camera_remove_message_callback(void *camera_handle, uint32_t cb_id) Unregisters a callback function.

The following table lists the 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 the 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 the preview frames.
int camera_release_preview_buffer(void *camera_handle, int buffer_index) Releases the preview buffer. The preview buffer must be released with this function after using it.
int camera_start_auto_focus(void *camera_handle) Starts the camera auto focusing operation.
int camera_stop_auto_focus(void *camera_handle) Stops the camera auto focusing operation.
int camera_start_capture(void *camera_handle, camera_capture_cb callback, void *user_data) Starts capturing 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 still images.

The following table lists the functions related to video recording.

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) Releases the video buffer. The video buffer must be released with this function after using it.

The following table list the functions related to controlling the camera device.

Prototype Description
int camera_set_command(void *camera_handle, int64_t command, void *value) Sets various commands and values to control the 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 the 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

Read the keyword and its value from the file. Recognize the categories by using the keyword list of the MSL camcorder, and save the member structure of MSL camcorder. Later, these values are used as attribute values or some other operation. The permission of this file is read-only to make sure the configuration files are read once before creating camcorder. Use a semicolon (“;”) to add comments in the config file.

The following table shows the description of the mmfw_camcorder.ini file.

Category Entry Description
General

General setting or information

SyncStateChange The API running type. It must be 1 (TRUE).
ModelName Model name of target
Video input

Setting list related to video input

UseConfCtrl Sets whether to use the configuration file. It must be 1 (TRUE).
ConfCtrlFile0 or 1 The name of the setting file to control the camera device.
VideosrcElement The source plugin which obtains the camera input buffer from the device
UseZeroCopyFormat Sets whether to use the zero copy format.
DeviceCount The number of camera device
SupportMediaPacketPreviewCb Sets whether the camera API supports media packet preview callback on the target.
Audio input

Setting list related to audio input

AudiosrcElement Audio source plugin, which obtains audio for the camcorder or voice recorder
AudiomodemsrcElement Audio source plugin which obtains audio for call recording
Video input

Setting list related to video output

DisplayDevice Supported output device list and the default value
Videosink Supported output surface list and the default value
VideosinkElementOverlay Plugin name for the Overlay output surface and the property setting list
VideosinkElementEvas Plugin name for the Evas output surface and the property setting list
VideosinkElementGL Plugin name for the GL output surface and the property setting list.
VideosinkElementNULL Plugin name for the NULL surface and the property setting list.
Video encoder Defines the video encoder list for video recording
Audio encoder Defines the audio encoder list for AV recording or voice recording
Capture

Setting list related to image capture

UseEncodebin Sets whether to use the encodebin to capture the image. It is recommended to keep this value as 0 (FALSE).
Record Setting value list for each recording mode. It is recommend to keep the values of the example config file.
Mux The mux plugin list related with the file container.

The following table shows the description of the mmfw_camcorder_dev_video_pri.ini file for the primary camera (usually the rear main camera) and the mmfw_camcorder_dev_video_sec.ini file for the secondary camera (usually the front camera).

Category Entry Description
Camera

Information about the camera

InputIndex Camera number to select (primary or secondary)
DeviceName Name of the camera module
PreviewResolution A list of all supported preview resolutions the user can set, as well as the default values for this camera device.
CaptureResolution A list of all supported capture resolutions the user can set, as well as the default values for this camera device.
VideoResolution A list of all supported video resolutions the 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 the 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

Camera flash settings

StrobeMode Supported strobe mode and default values. This is converted to a real value and used in the kernel internally.
Effect

Effect settings

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

Camera shooting settings

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

Image capture settings

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 supports zero shutter lag capture or not.
Detect

Detect function settings

DetectMode Supported detect mode list and default values.

References

Driver Configuration

Set the kernel .config values for the camera:

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

For more information about GStreamer, see http://gstreamer.freedesktop.org/documentation/ and http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html.

V4L2

For more information about V4L2, see http://v4l2spec.bytesex.org/spec-single/v4l2.html.

Radio

The radio interface part of the multimedia framework supports APIs to implement the following FM radio features.

  • Tune a frequency
  • Get and set a frequency
  • Scan all available frequencies
  • Seek up and down
  • Get the frequency signal

Radio.png

The interfaces to control the radio device are different to each other. Therefore, Tizen provides the Radio Hardware Abstraction Layer (HAL) to control various radio devices with a common interface. With the common interface, you can control the radio device on various chipsets used by the libmm-radio.

Porting OAL Interface

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

Radio HAL

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

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

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

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

Major Functions

The following table lists the functions related to initialization and deinitialization.

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

The following table lists the functions related to preparing and unpreparing the radio device.

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

The following table lists the functions related to opening and closing the radio device.

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

The following table lists the functions related to starting and stopping the radio device.

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

The following table lists the functions related to setting and getting the 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.

The following table lists the functions related to seeking for channels.

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;

The following table lists the functions related to muting and unmuting the radio device.

Prototype Description
radio_error_t radio_mute(void *radio_handle) Mutes the radio.
radio_error_t radio_unmute(void *radio_handle) Unmutes the radio.

The following table lists the functions related to getting the 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

The following figure illustrates the different audio layers.

Audio.png

  • PulseAudio
    • PulseAudio is a sound server accepting sound input from 1 or more sources and redirecting it to 1 or more sinks. PulseAudio has the following 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.
  • Audio HAL
    • Predefined interfaces for Audio Hardware Abstraction Layer (HAL)
    • Interface includes the 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

The following table lists the audio HAL interfaces.

Interface Description
audio_return_t audio_init(void **audio_handle) Initializes the audio HAL handle.
audio_return_t audio_deinit(void *audio_handle) De-initializes the 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) Notifies 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, PulseAudio and device configuration have to be modified by the vendor. The following table shows the PulseAudio configuration.

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

In this file, the PulseAudio daemon properties such as priority, log-level, resampling method, and default sample rate can be modified.

In Tizen, PulseAudio daemon must be running as only system mode not user mode.

/etc/pulse/client.conf Configuration file for the 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 does not support this mode.

  • Stream/device configuration
    • Stream map: Latency, volume and streams can be configured in this file.
    • Device map: Device types and device files can be configured in this file.

The following table shows examples of the the 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
The following list 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

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

Player.png


Porting OAL Interface

Playerplugin.png

There is no specific OAL for the multimedia player framework. As part OAL interface, the player plugins consists of the gst-openmax codec plugins and video/audio renderer plugins. For details of the gst-openmax plugin details, see Porting OAL Interface (Codecs). For more information about Avsystem for audio, see Audio), and X11 (UI-framework) for display, see Video.

Configuration

  • Configuration file
    • The multimedia player framework uses the mmfy_player.ini configuration file to set various parameters for selecting different codecs and display plugins.
    • The mmfy_player.ini configuration file is provided by the mmfw-sysconf-xxx package.
    • In the final stage of development, the permission for this file needs to be changed to read-only.
  • Configuring the player
    • File name: mmfw_player.ini
    • 1 player.ini file is needed in each board (or model).
    • Codec plugins for this board are located in the /usr/lib/gstreamer-0.10 directory. Changing the codec plugin does not mean modifying this .ini file because the player supports the auto plugin feature.
  • As needed, the following setting values can be used:
    • Exclude keyword element
      Having many codec plugins with the same rank and same feature causes problems in selecting the codec you want. Add the plugin name to exclude unwanted plugins.
      Setting this general selection keyword means that these codec plugins do not link in the player pipeline. The default value is ffdec_
      If you want to use the ffmpeg software codec plugin for testing, you can remove this ffdec_ keyword.
    • 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 software audio effect plugins based on arm architecture are used. Tf the platform is set to another architecture process, this value needs to be set to false. Making and using such a plugin is under review.

References

Display Driver Configuration for Samsung chipset

The following list 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

Codec

The following figure illustrates the codecs and their relations. It shows 2 types of codec plugins, the Gstreamer and OpenMAX.

Codec.png

  • Gstreamer codec plugin
    • The Gstreamer codec plugin can be linked and used easily to the Gstreamer pipeline, which is used in the multimedia framework.
  • OpenMAX codec plugin
    • Some of the codec vendors provide OpenMAX IL components and not Gstreamer plugins. Tizen provides the gst-omx plugins to use the OpenMAX IL components. The Gstreamer pipeline used in the multimedia framework can control and transfer data to OpenMAX IL component using the gst-omx plugin.
Description of each codec component
  • Gstreamer codec plugin
    The following figure shows an example of the decoder codec plugin 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, see References.
    Gstreamer codec plugin.png
    • In addition, to link a Gstreamer pipeline, the capability of the codec plugin can be negotiated with the linked element in the pipeline.
    • To get detailed information, such as the capability of an element, use the #gst-inspect (element name) command.
      Gst-inspect.png
  • OpenMAX component codec plugin
    The following figure shows the example of decoder codec plugin, which is provided as an OpenMAX component type.
    Openmax.png
    • To use the OpenMAX component in Gstreamer, the gst-openmax (open source) package is provided. 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 the gst-openmax plugin is the same as other Gstreamer plugins.
    • For more detailed information about this plugin, see http://www.freedesktop.org/wiki/GstOpenMAX. For more information about OpenMAX IL, see http://www.khronos.org/openmax/.
    • The gst-openmax plugin refers to a gst-openmax.conf configuration file. This file is included in the mmfw-sysconf package, and installed to the /usr/etc/gst-openmax.conf directory in the 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. The 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 decoders provide encoded data to derived GstOMXVideoDec and each input frame is provided in turn to the subclass's handle_frame callback. The GstVideoDecoder base class and derived subclass cooperate in the following way:

  1. Configuration
    • GstVideoDecoder calls the start() function when the decoder element is activated.
    • GstVideoDecoder calls the set_format() function 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() function.
    • The subclass calls the gst_video_decoder_finish_frame() or gst_video_decoder_drop_frame() function.
  3. Shutdown phase
    • The GstVideoDecoer class calls the stop() function.

Configuration

OpenMAX component codec plugin

The gst-omx plugin refers to a configuration file, such as gstomx.conf. This file is included in the gst-omx package, and installed in the /etc/xdg/gstomx.conf directory on the target device. The gstomx.conf file needs to change appropriately, according to vendors which provide OpenMAX component. The following figures lists the values of each item in the lists separated by commas. Each Gstreamer element is separated by a semicolon.

Gst-openmax.conf.png

The following figure shows an example.

Omx mpeg4dec.png

Each value needs to be changed appropriately, according to vendors who provide the OpenMAX component. When you are finished with these settings, the result is a Gstreamer type codec plugin, and you can test the codec the same way.

  • Using the codec plugin in the player
    • Because the player uses auto plugging, it does not need an additional setting.
      • If the decoder plugin has an 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 the /usr/etc/mmfw_player.ini file (mmfw-sysconf package), it is excluded in the player pipeline.
  • Using the codec plugin in the camcorder
    • Because the camcorder clarified its audio, video, and image encoder in the /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 2 devices. In Tizen, open source Bluetooth components like BlueZ and ObexD are used. Bluez and Obexd run as the daemon and there is an interface library Bluetooth Framework, used for applications to access BlueZ or ObexD over the D-Bus interface.

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

Bluetooth Low Energy function was implemented in BlueZ and bluetooth-frwk.

The following figure explains the Bluetooth architecture on Tizen.


Bluetooth.png

The Bluetooth framework provides dialogue for the user. It controls the BlueZ, ObexD, and PulseAudio daemons. Bluetooth provides a standard interface between the Bluetooth 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 can be different. The vendor provides the HCI configuration and the initial scripts. For example, Broadcom and Spreadtrum provide firmware and a loading tool. Tizen supports Bluetooth version 4.2. The supported profiles are GATT, FTP, OPP, MAP, PBAP, A2DP, AVRCP, HSP/HFP, RFCOMM, HID, HDP, and PAN. Bluetooth framework Tizen Bluetooth is based on the open source BlueZ project. BlueZ provides the DBUS API and based on it, Tizen BT framework provides the C Language API. It is recommended to use the Tizen Bluetooth framework.

The following components are necessary for Bluetooth:

  • Application
    • The user dialogue that controls the BlueZ, ObexD, and PulseAudio daemons
  • ObexD
    • The open source component
    • Object exchange daemon
    • Supports OPP, FTP, PBAP, SYNC, and MAP profile stack
  • BluetoothD
    • BluetoothD is the open souce component, Bluez 5.37 is supported
    • Bluetooth central daemon
    • Supports GAP, SDP, A2DP, AVRCP, HFP, HSP, and GATT profile stack
  • Bluetooth Subsystem
    • Provides the BT unix socket. Each protocol can be accessed by its socket.
    • Supports the L2CAP, RFCOMM, SCO, and HCI protocols
  • 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 the Bluetooth firmware to the Bluetooth chip.
    • Tizen and the chipset vendor need to implement this together.
    • Package: bluetooth-tools

Porting OAL Interface

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

  • bt-stack-up.sh
This script file is used to run the hardware specific script files to power up or start the Bluetooth 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 files to power down or stop the Bluetooth hardware along with the background processes, such as bluez and obexd.
  • bt-reset-env.sh
This script file is used to reset the Bluetooth chip by running the bt-stack-down.sh script along with the resource clean up.
Tizen BT Obex profiles

In Tizen, for the obex based profiles, the open source ObexD is used.

  • 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, such as UART speed and UART terminal (tty), to be opened specific to the chipset. These changes must be provided by the chipset vendors.

Configuration for the BCM4358 Bluetooth chipset by Broadcomm
  • hciattach
The bluez/tools/hciattach.c project 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 Bluetooth 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 the first Bluetooth activation
  • 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
  • Attach a serial device using UART HCI to the Bluetooth stack for a broadcom device:
hciattach /dev/ttySAC3 –S 3000000 bcm2035 3000000 flow
  • Run the Bluetooth daemon version 5.37:
bluetoothd
  • Bring the device up, set up the device name, and enable the SSP mode:
hciconfig hci0 up
hciconfig hci0 name “Tizen-Mobile”
hciconfig hci0 sspmode 1
  • Switch on the Bluetooth radio:
rfkill unblock bluetooth
  • Switch off the Bluetooth radio:
rfkill block bluetooth
Configuration for the sc2331 Bluetooth chipset by Spreadtrum
  • hciattach
The 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.
  • Registering the Bluetooth device:
The cp2-download tool is provided for downloading the firmware provided with Spreadtrum. This tool also downloads the Wi-Fi firmware at the booting time.
  • Install the following files in the target's /usr/lib/firmware directory:
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.
  • Attach a serial device using UART HCI to the Bluetooth stack:
hciattach -s 3000000 /dev/ttyS0 sprd 3000000 flow
  • Run the bluetooth daemon version 5.37:
bluetoothd
  • Bring the device up, set up the device name, and enable the SSP mode:
hciconfig hci0 up
hciconfig hci0 name “Tizen-Mobile”
hciconfig hci0 sspmode 1

References

Open source component version: BlueZ 5.37

For more information, see http://www.bluez.org/.

Reference kernel configuration for Bluetooth

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

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

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. The Linux wireless SW stack defines the WLAN hardware adaptation software 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.

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

The 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.

Porting OAL Interface

The 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 must be copied to the WLAN driver plugin directory, built, and installed before testing the Wi-Fi functionality. Because of Tizen platform requirement, the Wi-Fi driver must create the /opt/etc/.mac.info file, which has the MAC address of device.

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

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

Using the /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

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. For more information, see http://linuxwireless.org.
CONFIG_CFG80211
CONFIG_LIB80211
CONFIG_MAC80211 (Enable this flag, if the driver supports the softMAC feature)
  • The following configuration options must 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

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.

Nfc.png

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 is a daemon process to control the NFC chipset (such as NXP pn544). It provides the read and write service and basic P2P communication service, as well as the basic API for the client application. The NFC stack contains the required plugin, based on the NFC chipset. Currently, the 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 must be implemented 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 loads the libnfc-plugin.so library at runtime from the /usr/lib/libnfc-plugin.so directory. Any vendor-specific plugin is installed within the same path. The plugin must be written with predefined OAL API interfaces.

During initialization, the nfc-manager loads the nfc-plugin.so library, searches for the onload() function, and calls the function 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 interact with nfc-plugin, which implements the vendor specific OAL interfaces.

The following example shows the 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 the following structure. Use the net_nfc_oem_controller.h header file.

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 runtime. The NFC plugin loads when the nfc-manager is started and the plugin init() function is called to initialize the NFC chip.

int (*init) (net_nfc_oem_controller_init*);

The deinit() function the nfc-manager issues to deinitialize the NFC chip:

int (*deinit) (net_nfc_oem_controller_deinit *);
Sending the notification to the upper layer (NFC Service)

Refer to the phdal4nfc_message_glib.c file. The g_idle_add_full is used for handling the message in the NFC Service. You can use the callback client asynchronously in the client context. Post a message in queue, and the message is processed by a client thread.

Reference implementation of the NFC plugin

Sample code snippets cannot be reproduced. Code is proriatory. For reference, see the nfc-plugin-emul and nfc-plugin-nxp files.

Configuration

The nfc-plugin package must be saved to the /usr/lib/libnfc-plugin.so directory when installed. When the nfc-manager starts, it looks for the plugin library and loads it dynamically from this path.

References

Enable the following configuration options in the kernel .config.

Using Pn544: CONFIG_PN544_NFC
Using Pn65n: CONFIG_PN65N_NFC

API references available are under the Tizen_3.0_Porting_Guide#Appendix_2.

For more information, see http://nfc-forum.org/.

MTP

  • MTP exchanges can only occur between 2 products at a time, and in each communication, 1 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 can not initiate any actions, and can only send responses to operations sent by the initiator or send events.

Mtp-responder.png

  • In the Tizen system, the USB host is the initiator, and the USB device is the responder.


Porting OAL Interface

  • Tizen MTP initiator and responder do not have an OAL Interface.
  • There are extension possibilities of the MTP Transport layer.


Configuration

MTP Initiator
  • The MTP Initiator consist of 3 packages.
mtp-initiator daemon
mtp-initiator api
libmtp opensource
  • The MTP initiator does not operate independently. It requires the help of another module, such as USB.
  • When the USB device is connected to the host, the module must run the MTP initiator daemon.
MTP Responder
  • The MTP responder consist of 1 package.
mtp-responder daemon
  • The MTP responder does not operate independently. It requires the help of another module, such as USB.
  • 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

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 Description Parameter
net_nfc_oem_controller_init init; Initializes the NFC chip. net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_deinit deinit; Deinitializes the NFC chip. None
net_nfc_oem_controller_register_listener register_listener; Registers a callback function for a tag event, SE event, and llcp event. target_detection_listener_cb target_detection_listener: The tag event callback function

se_transaction_listener_cb se_transaction_listener: The SE event callback function

llcp_event_listener_cb llcp_event_listener: The llcp event callback function

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_unregister_listener unregister_listener; Releases a callback function for a tag event, SE event, and llcp event. None
net_nfc_oem_controller_check_firmware_version check_firmware_version; Checks the firmware version of the NFC chip. net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_update_firmware update_firmware; Updates the NFC chip firmware. net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_get_stack_information get_stack_information; Gets the list of supported tags and the current firmware version. net_nfc_stack_information_s: Pointer value to get the information of support tags and the current firmware version

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_configure_discovery configure_discovery; Delivers the config information on discovery. net_nfc_discovery_mode_e: The start/stop mode

net_nfc_event_filter_e config: The information for tag filtering

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_get_secure_element_list get_secure_element_list; Gets the information of the 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 the secure element

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_set_secure_element_mode set_secure_element_mode; Sets the secure element to use. net_nfc_secure_element_type_e: Secure element information

net_nfc_secure_element_mode_e: The mode information to set

net_nfc_error_e: Returns an error code on failure.

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

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_connect disconnect; Disconnects the connected tag/target. net_nfc_target_handle_s: The tag/target handle for disconnecting

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_check_ndef check_ndef; Checks the tag to for ndef support. net_nfc_target_handle_s: The tag handle to check ndef

int: The max size supported in the tag

int: The real data size saved in the tag

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_check_target_presence check_presence; Checks if a tag exist in the RF range. net_nfc_target_handle_s: The tag handle to check presence

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_read_ndef read_ndef; Reads ndef data in a tag. net_nfc_target_handle_s: The tag handle to read

data_s: The pointer value to save the ndef data

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_write_ndef write_ndef; Writes the data to the tag. net_nfc_target_handle_s: The handle to write

data_s: The data to write

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_make_read_only_ndef make_read_only_ndef; Makes the tag to a read only tag. net_nfc_target_handle_s: The target tag handle

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_transceive transceive; Sends and receives the low command to the tag or target. net_nfc_target_handle_s: The tag or target handle to transceive

net_nfc_transceive_info_s: The pointer value included command or data to send and data to receive

data_s: The pointer value to send the information of context

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_format_ndef format_ndef; Formats the tag. net_nfc_target_handle_s: The tag handle to format

data_s: The key value to send the tag for formatting

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_exception_handler exception_handler; When the nfc-manager faces an unwanted exception, it tries to deinitialize and initialize the stack before unregistering and registering the callback function. None
net_nfc_oem_controller_is_ready is_ready; Checks the status of the NFC stack. net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_llcp_config config_llcp; Sets the llcp configuration (miu, lto, wks, option). net_nfc_target_handle_s: The target handle to set llcp

net_nfc_error_e: Returns an error code on failure.

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

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_llcp_activate_llcp activate_llcp; Activates the llcp functionality. net_nfc_target_handle_s: The target handle to activate

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_llcp_create_socket create_llcp_socket; Creates the llcp socket net_nfc_llcp_socket_t: The pointer value to receive the socket 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: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

net_nfc_oem_controller_llcp_bind bind_llcp_socket; 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: Returns an error code on failure.

net_nfc_oem_controller_llcp_listen listen_llcp_socket; Sets the socket to listen. net_nfc_target_handle_s: The target handle

uint8_t: The service name to listen

net_nfc_llcp_socket_t socket: Socket information

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

net_nfc_oem_controller_llcp_accept accept_llcp_socket; Accepts the connect request in listening status. net_nfc_llcp_socket_t socket: Socket information to accept

net_nfc_error_e: Returns an error code on failure.

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

net_nfc_llcp_socket_t socket: Socket information

uint8_t: Service name to connect

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

net_nfc_oem_controller_llcp_connect connect_llcp; Connects to the server with access point (port number). net_nfc_target_handle_s: The target handle

net_nfc_llcp_socket_t socket: Socket information

uint8_t service_access_point: Access point number

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

net_nfc_oem_controller_llcp_disconnect disconnect_llcp; Disconnects the llcp link. net_nfc_target_handle_s: Socket information to disconnect

net_nfc_llcp_socket_t socket: The information of the socket to disconnect

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

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

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_llcp_recv recv_llcp; Receives the data using the llcp link. net_nfc_target_handle_s: The target handle 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: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

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

net_nfc_llcp_socket_t socket: Socket information to send

data_s: The data to send

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

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

net_nfc_llcp_socket_t socket: The socket information to reject

net_nfc_error_e: Returns an error code on failure.

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

net_nfc_llcp_socket_t socket: The socket information

data_s: The data to send

uint8_t service_access_point: The service access point to send

net_nfc_error_e: Returns an error code on failure.

void: The value to control the context (can be set to NULL)

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

net_nfc_llcp_socket_t socket: The socket information to reject

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_llcp_get_remote_config get_remote_config; Gets te llcp socket config information of the peer device. net_nfc_target_handle_s: The peer target handle

net_nfc_llcp_config_info_s: The pointer value to get config information of peer device's llcp socket

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_llcp_get_remote_socket_info get_remote_socket_info; Gets the llcp socket information of the peer device. net_nfc_target_handle_s: The peer target handle

net_nfc_llcp_socket_t socket: The llcp socket information

net_nfc_llcp_socket_option_s: The pointer value to save the information of remote socket

net_nfc_error_e: Returns an error code on failure.

net_nfc_oem_controller_sim_test sim_test; Tests the SWP link with SIM and NFC chipset. net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_test_mode_on test_mode_on; Changes the NFC chip to test mode. (Test mode exists only in the NXP case. If there are none, it does not need to implemented.) net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_test_mode_off test_mode_off; Changes the status of the NFC chip from test mode to normal mode. (Test mode exists only in the NXP case. If there are none, it does not need to implemented.) net_nfc_error_e: Returns an error code on failure.
net_nfc_oem_controller_support_nfc support_nfc Checks each the device file of each chip. If the device file is not found, the function returns NET_NFC_NOT_SUPPORTED.
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox