Porting Guide

From Tizen Wiki
Jump to: navigation, search

Contents

Introduction

About Tizen

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

Purpose of this document

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

Tizen Architecture

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

what_is_tizen_architecture.png

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

The Core Layer

Tizen Core Services

Application Framework

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

Base

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

Connectivity

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

Graphics and UI

Mobile profile: Graphics and UI consist of the system graphic and UI stacks, so-called Native Framework, which is a port of Samsung bada graphics stack also called OSP (Open Services Platform, C++ APIs) adopted for Linux and X11. This port also internally utilizes EFL (Enlightenment Foundation Libraries) for X11-based window management, and phone indicator. Specialized control for fluent animations is available in addition, it utilizes EFL's elementary framework. The Native Framework has built-in various input methods and OpenGL® ES APIs.

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.

IVI profile: WebKitEFL is available like for the Mobile profile. Selection of other graphics/UI toolkits is device manufacturer's or integrator's individual choice.

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 SMS, MMS, Email, and IM.

Multimedia

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

PIM (Personal Information Management)

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

Security

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

System

System consists of system and device 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.
  • System upgrade.
  • Mobile device management.

Telephony

Telephony consists of cellular functionalities communicating with the modem:

  • Managing call-related and non-call-related information and services for UMTS and CDMA.
  • Managing packet service and network status information for UMTS and CDMA.
  • Managing SMS-related services for UMTS and CDMA.
  • Managing SIM files, phone book, and security.
  • Managing SIM Application Toolkit services for UMTS.

More details can be read on Tizen Telephony Porting Guide.

Web

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

Development Environment Setup

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

Getting Source Code&Build

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

https://review.tizen.org/git/

Refer to below link for more information

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

Platform Build

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

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

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

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

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

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

Kernel Build

Follow below steps to build the Tizen ARM kernel. (Tizen 2.0 - 2.2)

  1. Install and setup cross compile tools on your system if the target and your host are different (e.g., x86).
  2. You may use Linaro toolchain binaries or Ubuntu package of them and have your environment setup for the cross tools (e.g., export CROSS_COMPILE=....)
  3. If your kernel source has been used to create binaries for other architecture, please start with cleaning them up.
    $ make distclean
  4. Setup the .config file for RD-210
    $ make ARCH=arm trats_defconfig
  5. Or for RD-PQ
    $ make ARCH=arm trats2_defconfig
  6. Then, after reconfiguring per your needs (e.g., make ARCH=arm menuconfig) or using the stock configuration (no modifications), build it.
    $ make ARCH=arm uImage
  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. Send the images to the target via lthor
    $ lthor arch/arm/boot/uImage usr/tmp-mod/modules.img
  9. Or, you may make your own tar file from the two files
    $ tar cf FILENAME_YOU_WANT.tar -C arch/arm/boot uImage -C ../../../usr/tmp-mod modules.img


Follow below steps to build the Tizen-next kernel. (Experimental. Does not fully support Tizen 2.2 on 2013/8/30. This is the basis for the Tizen-next development) The git path is /platform/kernel/linux-3.10.git

  1. Install and setup cross compile tools on your system if the target and your host are different (e.g., x86).
  2. You may use Linaro toolchain binaries or Ubuntu package of them and have your environment setup for the cross tools (e.g., export CROSS_COMPILE=....)
  3. If your kernel source has been used to create binaries for other architecture, please start with cleaning them up.
    $ make distclean
  4. Setup the .config file (it supports device tree.)
    $ make ARCH=arm tizen_defconfig
  5. Then, after reconfiguring per your needs (e.g., make ARCH=arm menuconfig) or using the stock configuration (no modifications), build it.
    $ make ARCH=arm uImage
  6. Create dtb
    $ make ARCH=arm dtbs
  7. Include dtb file into uImage if needed. The example below is for RD-PQ.
    $ cat arch/arm/boot/uImage arch/arm/boot/dts/exynos4412-trats2.dtb > uImage
  8. At this point (2013/8/30), we do not have kernel modules included. But they will be included afterwards.
  9. Send the images to the target via lthor
    $ lthor arch/arm/boot/uImage

Image Build

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

https://review.tizen.org/gerrit/gitweb?p=profile/$profile/meta-$profile.git;a=tree

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

ie:

https://review.tizen.org/gerrit/gitweb?p=profile/ivi/image-configurations.git;a=blob;f=packaging/image-configurations.spec;;hb=HEAD

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

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

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

https://lists.tizen.org/pipermail/product-dev/2014-March/000189.html

Tizen Bootup Overview

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

Boot-1.png

Kernel Bootup

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

Platform Bootup

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


Below figure shows you early boot sequence after starting kernel

Boot-2.png

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


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


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


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

Boot-3.png

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


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

BSP Customization

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


Bootloader Fundamentals

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

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

Bootloader Setup and Build

Follow the steps to build the Tizen boot loader

  1. Install and setup cross compile tools on your system if the target and your host are different (e.g., x86).
  2. You may use Linaro toolchain binaries or Ubuntu package of them and have your environment setup for the cross tools (e.g., export CROSS_COMPILE=....)
  3. Start with cleaning u-boot source up.
    $ make distclean
  4. Setup the configration for RD-210
    $ make exynos_trats_config
  5. or for RD-PQ
    $ make exynos_trats2_config
  6. Build u-boot
    $ make ARCH=arm
  7. Once the build is successful, u-boot-mmc.bin file is created.
  8. Create a bootloader tarball to download u-boot binary onto the target
    $ tar cvf bootloader.tar u-boot-mmc.bin

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

Bootloader Commands Support

The Tizen boot loader supports various commands, which are used with u-boot prompt before loading the kernel. Below are some examples of the commands used in boot loader.

   Example:
   usb
   reset
   printenv
   setenv
   saveenv
   ramdump
   pit
   help

You can find the details about each command using the help command followed by the command name.

   Example:
   <u-boot prompt> help ramdump
   ramdump - Kernel lockup/panic logger
   Usage:
   ramdump show klog/dlog - log print on console
   ramdump show blog <index[-1(default), 0]> - log print on console
   ramdump save <ram/klog/dlog/blog/fb> - log save as file on UMS
   ramdump logo - draw logo
   ramdump check - check header info

Bootloader Kernel Parameters

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

   Example:
   console=ttySAC2,115200n8 
   fbmem=24M@0x66800000 
   csa=/dev/mmcblk0p1 
   bootloader_log=1167@0x62d08010

Kernel Fundamentals

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


Kernel Configurations

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

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

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

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

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


Tizen File System

Virtual Filesystem (VFS )

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

Filesystem.png

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

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


Tizen Partition Layout

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

Partitionlayout.png

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

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

File-system Hierarchy Standard in Tizen

Each partition has this hierarchy:

Filesystemhierarchy.png

Supported filesystems in Tizen

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

Default File-system in Tizen

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


Configuration

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


Reference

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

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

MMC/SD/SDIO

Description

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

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

Mmc.png

MSHCI/SDHCI Features Overview

The MMC/SD/SDIO driver supports these features:

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

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

MMC subsystem structure is divided into three parts:

MMC block device driver /driver/mmc/card/

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

Host controller driver /driver/mmc/host/

Hotplug MMC event handling in Tizen

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


Reference

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


Kernel Configuration for MMC Interface

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


Kernel Configuration for SD/SDIO Interface

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

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

System

systemd

Description

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


Below figure shows you the systemd architecture.

Systemd arch.PNG


systemd Utility

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


systemd target

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


systemd daemon

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


systemd core

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


systemd library & Linux Kernel

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

System Framework

Description

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

Systemframework.png

The System framework contains these sub-components:

System server

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

Power manager

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

Power manager conditional state transition

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

Conditional state transition

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

Unlock : allow system to enter lower state than specific state

Controlling the device’s power status and sleep mode.

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

Device manager

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

USB manager

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

System OAL

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

Porting OAL Interface

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

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

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

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

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

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

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

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

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

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

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

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

	int	(*OEM_sys_image_enhance_info) (int *value);

	int	(*OEM_sys_set_display_frame_rate) (int value);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

OAL API reference implementation:

   Sample implementation code for OEM_sys_get_backlight_brightness()

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

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

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

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

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

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

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

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

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

	return ret;
    }

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

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

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

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

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

	close(fd);

	return 0;
}

Power manager

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

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

Vibrator

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

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

Image Enhancement

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

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

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

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

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

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

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

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

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

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

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

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

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

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

(0 : OUTDOOR_OFF, 1: OUTDOOR_ON)

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

(0 : OUTDOOR_OFF, 1: OUTDOOR_ON)

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

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

Optional

Light

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

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

(0 <= value <= MAX_BACKLIGHT_BRIGHTNESS).

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

(0 <= value <= MAX_BACKLIGHT_BRIGHTNESS).

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

(0 <= value <= TORCH_MAX_BRIGHTNESS).

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

(0 <= value <= TORCH_MAX_BRIGHTNESS).

Optional

Keytouch OAL Interfaces

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

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

Battery

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

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

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

Optional

Utility

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

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

Configuration

None

Reference

Packagename: device-manager-plugin-exynos

Include file : devman_define_node_path.h

Source file: device_manager_plugin_exynos.c

PM Kernel Configuration

Power management options
[*] Power Management support

Linux Suspend Resume Code is located at kernel/power

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

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

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

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

[*] CPU idle PM support


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

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

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

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

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

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


CPU Hotplug

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

To enable this feature, select this configuration:

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

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

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

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


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

Sensor Framework

Description

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

Types of Sensors

Tizen supports individual plugin frameworks for these sensors:

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

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

Sensorframework.png

Accelerometer sensor

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

Gyroscope sensor

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

Proximity sensor

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

Motion sensor

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

Geomagnetic sensor

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

Light sensor

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

Components of Sensor Framework

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

Here's the description of the sensor framework components:

Sensor Library

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

Sensor Server

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

Type of plugins in sensor framework

Sensor Plugin

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

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


Porting OAL Interface

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

Processor Plugin

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

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

	accel_processor();
	virtual ~ accel_processor();

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

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

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

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

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

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

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

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

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

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

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

Failure-False

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

param[out] vod *property_data specification data

Success- 0

Failure – Negative value [-1]

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

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

Success- 0

Failure – Negative value [-1]

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

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

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

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

#include <vconf.h>

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	accel_processor *processor = (accel_processor*)inst;

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

	return (void*)NULL;
}

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

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

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

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

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

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

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

	processor->lock();

	if(processor->m_rotation_cb_client > 0)	{

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	cprocessor_module::unlock();
	return ret;
}

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

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

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

	return true;
}

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

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

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

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

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

	return true;
}

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

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

	return true;
}

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

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

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

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

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

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

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

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

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

	return 0;

}

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

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

	return (cmodule*)inst;
}



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

Sensor Plugin

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

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

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

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

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

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

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

#include <csensor_module.h>

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

#define ACC_DEV_NODE "/dev/accelerometer"

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

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

#define SENSOR_NODE_LENGTH 256
#define CHIP_NAME_LENGTH   50

#define REACTIVE_ALERT_OFF	0
#define REACTIVE_ALERT_ON	3

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


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

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

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

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

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

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

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

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

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

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

	csensor_module::lock();	

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

	csensor_module::unlock();

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

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

	DBG("Sensor, invoked\n");

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

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

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


	return ret;
}

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

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

	return -1;
}

long clsm330dlc_accel::value(int id)
{

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

	return -1;
}

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

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

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

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

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

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

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

	return m_port[idx];
}

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

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

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

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

	return true;
}

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

	m_client ++;

	if (m_client > 1) {
		return true;
	}

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

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

		return false;
	}

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

		return false;
	}

	return true;
}

bool clsm330dlc_accel::stop(void)
{

	int sensor_enable = 0;

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

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

		return false;
	}

	close(accel_file_handle);

	return true;
}

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

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

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

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

	return 0;
}

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

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

	return value;

}

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

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

	return -1;
}

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

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

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

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

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

				if (!strcasecmp(hw_name,orig_name)) {

	return find_node;
}

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

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

	return (cmodule*)sample;
}

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

//! End of a file

Filter Plugin

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

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

	caccel();
	virtual ~ caccel();

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

	bool is_data_ready(bool wait = false);

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

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

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

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

	int check_hw_node(void);

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

	void reset(void);

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

Configuration

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

Each configuration file supports the following fields and values:

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

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

Example of a sample sf_sensor.conf configuration file:

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

Example of a sample sf_processor.conf

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

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

You don't need to edit datastream configure file.

Reference

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

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

/dev/input/event1/

/dev/input/event2/

/dev/input/event3/

/dev/input/event4/

/dev/input/event5/

Proximity CONFIG_INPUT_GP2A
Light sensor CONFIG_INPUT_GP2A
Electronic compass CONFIG_SENSORS_AK8975

Graphics and UI

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

Graphicsarchitecture.png

Description

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

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

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

OpenGL

3D Graphics Library

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

Opengl.png

Description

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

Description of each component of 3D Graphics

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

The following diagram gives a brief overview of EGL interface.

Egl interface.png

Porting

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

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

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

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

eglext.h

eglplatform.h

/usr/include/GLES gl.h

glext.h

glplatform.h

/usr/include/GLES2 gl2.h

gl2ext.h

gl2platform.h

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

libGLESv1_CM.so

libGLESv2.so

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

X server

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

Input Driver

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

Input.png

Description

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

Porting OAL Interface

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

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

Configuration

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

Video Driver

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

Video.png

Description

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

Porting OAL Interface

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

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

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

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

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

To implement a driver module, refer to this link :

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

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

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

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

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


References Header:

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


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

Reference Header

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

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

Reference Header

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

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

Reference Header

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

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

Reference Header

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

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

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

Configuration

None

References

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

Xorg Input driver

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


Khronos API Implementers Guide

www.khronos.org/registry/implementers_guide.pdf

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


Kernel configurations for input devices
CONFIGURATION PURPOSE
CONFIG_INPUT

CONFIG_INPUT_MISC

CONFIG_INPUT_EVDEV

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

CONFIG_INPUT_MOUSE_PSAUX

For mouse devices

Multimedia

Camcorder

Description

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

MMFWCamcorder.png

  • Camera source plugin for GStreamer
    • Gets camera data (preview or captured image) from the camera device
    • Inherit “GstPushSrc”
  • Config files

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

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

Porting OAL Interface

  • GStreamer Camera plugin
    • Because the kernel interfaces to control camera device can be different for different chipsets, the camera plugin should be implemented specifically for each chipset. To develop a new plugin, refer to the gsteamer plugin development guide: (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html)
    • Any third party developer who wants to implement camera source plugin needs to derive it from GstPushSrc.
    • When the camera source plugin is moving from NULL to READY state (GST_STATE_CHANGE_NULL_TO_READY), it should open the camera device using the open system call.
    • In the plugin’s start virtual function (GstBaseSrc’s start function), the required formats and parameters should be set using IOCTL system calls and also the required number of buffers should be obtained according to the IO method.
    • In the plugin’s create virtual function (GstBaseSrc’s create function), the plugin should get the raw buffers from the camera driver and needs to be pushed to the downstream element.
    • Extra properties should be implemented for capture and setting.
Name Type Description
camera-id int Index number of camera to activate(front,rear etc)
capture-fourcc unsigned int Fourcc value for capture format
capture-jpg-quality unsigned int Quality of captured image(such as JPEG compressibility)
capture-width unsigned int Width of captured image
capture-height unsigned int Height of capured image
capture-count unsigned int Number to capture image
provide-exif boolean Whether EXIF data is included in captured image
vflip boolean Flip camera input vertically
hflip boolean Flip camera input horizontally
  • "gst-interfaces" should be applied for capture and setting. Refer "pkgs/gst-plugins-base0.10/gst-libs/gst/interfaces/cameracontrol* and colorbalance*" files.

return value of All gst_camera_control_* APIs:

-> TRUE : SUCCESS

-> FALSE : FAILURE

Interface function name Description
gst_camera_control_set_capture_command (GstCameraControl* control, GstCameraControlCaptureCommand cmd) Set capture command (start, stop, stop multishot).

This is async API. Camera source plugin has a command queue in it.

Control - is casted instance of camera source plugin cmd- enumerations for camera capture command.

   typedef enum
   {
      GST_CAMERA_CONTROL_CAPTURE_COMMAND_NONE,
      GST_CAMERA_CONTROL_CAPTURE_COMMAND_START,
      GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP,
      GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP_MULTISHOT,
   } GstCameraControlCaptureCommand;
gst_camera_control_set_exposure( GstCameraControl *control, gint type, gint value1, gint value2) Set exposure mode.

1] control - is casted instance of camera source plugin 2] type - enumerations for camera control exposure types.

   typedef enum
   {
      GST_CAMERA_CONTROL_F_NUMBER,
      GST_CAMERA_CONTROL_SHUTTER_SPEED,
      GST_CAMERA_CONTROL_ISO,
      GST_CAMERA_CONTROL_PROGRAM_MODE,
      GST_CAMERA_CONTROL_EXPOSURE_MODE,
      GST_CAMERA_CONTROL_EXPOSURE_VALUE,
   } GstCameraControlExposureType;

3] value1, value2

- ISO, Program mode and exposure mode are use only "value1"
- F number, shutter speed, exposure value are use both (value1 and value2. value1 is numerator and value2 is denominator of them)
gst_camera_control_get_exposure Get exposure mode.
gst_camera_control_set_strobe( GstCameraControl *control, gint type, gint value) Set strobe(flash) mode.

1] control

- is casted instance of camera source plugin

2] type - if camera module supports a strobe (flash), "STROBE_MODE" should be supported. Others (control, capabilities, status, ev) are optional.

   /**
    * Enumerations for Camera control Strobe types.
    */
   typedef enum
   {
      GST_CAMERA_CONTROL_STROBE_CONTROL,
      GST_CAMERA_CONTROL_STROBE_CAPABILITIES,
      GST_CAMERA_CONTROL_STROBE_MODE,
      GST_CAMERA_CONTROL_STROBE_STATUS,
      GST_CAMERA_CONTROL_STROBE_EV,
   } GstCameraControlStrobeType;

3] value

- is dependent on camera device. 0 is enough for API test.
gst_camera_control_get_strobe Get strobe(flash) mode
gst_camera_control_set_detect( GstCameraControl *control, gint type, gint value) Set detection mode.

1] control

- is casted instance of camera source plugin

2] type - enumerations for camera control Face detection types.

   typedef enum
   {
      GST_CAMERA_CONTROL_FACE_DETECT_MODE,
      GST_CAMERA_CONTROL_FACE_DETECT_NUMBER,
      GST_CAMERA_CONTROL_FACE_FOCUS_SELECT,
      GST_CAMERA_CONTROL_FACE_SELECT_NUMBER,
      GST_CAMERA_CONTROL_FACE_DETECT_STATUS,
   } GstCameraControlFaceDetectType;

3] value

- is dependent on camera device. 0 is enough for API test
gst_camera_control_get_detect Get detection mode
gst_camera_control_set_zoom(GstCameraControl *control, GstCameraControlZoomType type, gint value) Set zoom mode and level.

1] Control - is casted instance of camera source plugin such as GstCameraControl

*control = NULL;
control = GST_CAMERA_CONTROL(camerasrc_plugin);

2] type - enumerations for camera control zoom types.

   typedef enum
   {
      GST_CAMERA_CONTROL_DIGITAL_ZOOM,
      GST_CAMERA_CONTROL_OPTICAL_ZOOM,
   } GstCameraControlZoomType;

3] value (zoom level)

- is dependent on camera device. 0 is enough for API test.
gst_camera_control_get_zoom Get zoom mode and level
gst_camera_control_set_focus( GstCameraControl *control, gint mode, gint range) Set focus mode and range.

1] control

- is casted instance of camera source plugin

2] mode

- is dependent on camera device. 0 is enough for API test.

3] range

- is dependent on camera device. 0 is enough for API test.
gst_camera_control_get_focus Get focus mode and range
gst_camera_control_start_auto_focus( GstCameraControl *control) Start auto focusing.

1] control

- is casted instance of camera source plugin.
gst_camera_control_stop_auto_focus( GstCameraControl *control) Stop auto focusing

1] control

- is casted instance of camera source plugin
gst_camera_control_set_focus_level( GstCameraControl *control, gint manual_level) Set focusing level for manual focus

1] control

- is casted instance of camera source plugin

2] manual_level

- is dependent on camera device. 0 is enough for API test.
gst_camera_control_get_focus_level Get focusing level for manual focus
gst_camera_control_set_auto_focus_area( GstCameraControl *control, GstCameraControlRectType rect) Set auto focusing area.

1] control

- is casted instance of camera source plugin

2] rect - struct GstCameraControlRectType brief For touch auto focusing area

   typedef struct {
      gint x;
      gint y;
      gint width;
      gint height;
   }GstCameraControlRectType;
gst_camera_control_get_auto_focus_area Get auto focusing area
gst_camera_control_set_wdr( GstCameraControl *control, gint value) Set wide dynamic range (wdr) mode.

1] control

- is casted instance of camera source plugin

2] value

- is dependent on camera device. 0 is enough for API test
gst_camera_control_get_wdr Get wide dynamic range mode
gst_color_balance_set_value Set color balance value (brightness, contrast, saturation, sharpness, white balance, color tone)
gst_color_balance_get_value Get color balance value (brightness, contrast, saturation, sharpness, white balance, color tone)
  • Extra signal should be implemented to get captured image
Name Proto type Description
still-capture Void user_function(GstElement *object,
GstBuffer *arg0,
GstBuffer *arg1,

GstBuffer *arg2, Gpointer user_data);

Signal callback is called with captured image

(arg0: main image, arg1:thumbnail image, arg2:screennail image) if user sets capture command

To understand the above description, an example is provided below to explain how to implement the zoom feature in the camera plugin, which will be used by the camcorder framework.

  1. The camcorder framework will invoke gst_camera_control_set_zoom( GstCameraControl *control, gint type, gint value ).
  2. The above function will in turn invoke the function. gst_camerasrc_control_set_zoom( GstCameraSrc* camerasrc, gint type, gint value ), which should be implemented in the camera plugin.
  3. The above will call the required IOCTL.

CODE SNIP


/*Invoked by Camcorder*/
ret = gst_camera_control_set_zoom(control, zoom_type, zoom_level);


/*Inside gst-plugin base*/

gst_camera_control_set_zoom( GstCameraControl *control, gint type, gint value )
{
	GstCameraControlClass *klass = GST_CAMERA_CONTROL_GET_CLASS( control );

	if( klass->set_zoom )
	{
		return klass->set_zoom( control, type, value );
	}

	return FALSE;
}

/*Camera Plugin implementation*/


gst_camera_src_control_interface_init( GstCameraControlClass *klass )
{
klass->set_zoom = gst_camera_src_control_set_zoom;
}

gst_camera_src_control_set_zoom( GstCameraControl* control,  gint type, gint value )
{
Type* this = (Type*)control; \
return gst_camerasrc_control_set_zoom( this, type, value ); \
} 

gst_camerasrc_control_set_zoom( GstCameraSrc* camerasrc, gint type, gint value )
{
gst_camerasrc_debug( "" );

int error = CAMERASRC_ERROR;
g_return_val_if_fail( camerasrc, FALSE );
switch( type )
{
	case GST_CAMERA_CONTROL_DIGITAL_ZOOM:
			error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_DIGITAL_ZOOM, value );
			break;
	case GST_CAMERA_CONTROL_OPTICAL_ZOOM:
			error = camerasrc_set_control (camerasrc->v4l2_handle, CAMERASRC_CTRL_OPTICAL_ZOOM, value );
			break;
	default:
		gst_camerasrc_debug( "Not supported type." );
		return FALSE;
}

return TRUE;
}

//…
Finally the ioctl call is made

//…
int err = CAMERASRC_ERR_UNKNOWN;\
	struct v4l2_control control;\
	control.id = cid;\
	control.value = in_value;\
	camsrc_info("[VIDIOC_S_CTRL] >> [%x] request with value %d", cid, in_value); \
	err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control);\
	if(err != CAMERASRC_SUCCESS) {\
		return err;\
	}



int _camerasrc_ioctl(camerasrc_handle_t *handle, int request, void *arg)
{
int fd = handle->dev_fd;
	
do {
	err = ioctl (fd, request, arg);
} while (-1 == err && EINTR == errno);

……


return CAMERASRC_SUCCESS;
}

Configuration

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

References

Driver Configuration
Set the kernel .config values for the camera like this:
CONFIG_VIDEO_DEV = y
CONFIG_VIDEO_SAMSUNG = y
CONFIG_VIDEO_SAMSUNG_V4L2 = y
CONFIG_VIDEO_FIMC = y
CONFIG_VIDEO_FIMC_MMAP_OUTPUT_CACHE = y
CONFIG_VIDEO_FIMC_MIPI = y
CONFIG_VIDEO_FIMG2D = y
CONFIG_VIDEO_JPEG = y
CONFIG_VIDEO_MFC5X = y
Kernel Node
For Camera		:   /dev/video1       
Other CAMIF interfaces	:   /dev/video(0-3)
  • Camera source plugin makes direct use of V4L2 ioctls to interact with the camera driver. The list of ioctls is:
Driver methods Description
VIDIOC_S_CTRL Set the value of control.
VIDIOC_G_CTRL Get the value of control.
VIDIOC_S_PARM Set the value parameter.
VIDIOC_G_PARM Get the value of parameter.
VIDIOC_STREAMON START capture or output process during streaming.
VIDIOC_STREAMOFF STOP capture or output process during streaming.
VIDIOC_QBUF Enqueue an empty (capturing) or filled (output) buffer in the driver's incoming queue.
VIDIOC_DQBUF Dequeue a filled (capturing) or displayed (output) buffer from the driver's outgoing queue.
VIDIOC_REQBUFS Initiate Memory Mapping or User Pointer I/O.
VIDIOC_QUERYBUF Query the status of a buffer. To map the buffers call VIDIOC_QUERYBUF for each buffer to get the details about the buffer, and call mmap() to map it.
VIDIOC_S_JPEGCOMP Set JPEG encode parameters.
VIDIOC_G_JPEGCOMP Get JPEG encode parameters.
VIDIOC_ENUM_FMT Enumerate image formats.
VIDIOC_ENUM_FRAMESIZES Enumerate frame sizes.
VIDIOC_ENUM_FRAMEINTERVALS Enumerate frame intervals.
VIDIOC_S_INPUT Query or select the current video input.
VIDIOC_QUERYMENU Enumerate menu control items.
VIDIOC_QUERYCTRL Enumerate control items.
VIDIOC_QUERYCAP Query device capabilities.

Radio

Radio.png

Description

The radio interface part of the multimedia framework supports APIs to implement the following FM radio features, using Linux V4L2 interfaces.

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

Porting OAL Interface

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

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

Configuration

None

References

Radio V4L2 interface for reference.
Driver methods Description
VIDIOC_QUERYCAP Query device capabilities
VIDIOC_S_TUNER Set tuner attributes
VIDIOC_S_CTRL Set the value of a control
VIDIOC_G_CTRL Get the value of a control
VIDIOC_S_FREQUENCY Set tuner or modulator radio frequency
VIDIOC_G_FREQUENCY Get tuner or modulator radio frequency
VIDIOC_S_HW_FREQ_SEEK Seek radio frequency
VIDIOC_QUERYCTRL Enumerate controls
VIDIOC_G_TUNER Get tuner attributes
Radio frequency value setting
The V4L2 interfaces VIDIOC_S_FREQENCY and VIDIOC_G_FREQUENCY configures and retrieves the frequency value in (MHz) /(16 * 1000). It requires V4L2_TUNER_CAP_LOW capability interface issued to the driver.

If libmm-radio gives VIDIOC_S_FREQUNCY with 140000, then it stands 87.5Mhz (=1400000/(16*1000))

Radio signal strength
The V4L2 interface VIDIOC_G_TUNER retrieves the signal strength which, is the unit of dbuV.
V4L2 specification
http://v4l2spec.bytesex.org/spec-single/v4l2.html

Audio

Audio.png

Description

  • Avsystem
    • Avsystem is a native Tizen component providing an API for handling the stream and the sound path in the upper layer. Avsystem has these significant features:
      • Provide interfaces for stream, such as open, close, read, write, etc.
      • Provide interfaces for sound path selections and switching.
      • Acquire the handle of session and reads (writes) stream data from (to) pulseaudio.
      • Control sound path and make alsa-scenario string from a given input, output, and stream type.
  • PulseAudio
    • PulseAudio is a sound server accepting sound input from one or more sources and redirecting it to one or more sinks. PulseAudio has these significant features:
      • Software mixing of multiple audio streams
      • Support for multiple audio sources and sinks
      • An extensible plugin architecture with support for loadable modules
      • Low-latency operation
      • Support bluetooth audio devices
  • asound.conf
    • A configuration file for ALSA drivers
    • Most applications will work without them. They are used to allow extra functionality, such as routing and sample-rate conversion, through the alsa-lib layer.
    • If you change this file, you need to run a command like this:
      sudo /etc/init.d/alsa-utils restart
    • Tizen uses this for defining pcm stream in MMFW

Porting OAL Interface

  • Avsystem
    • Avsystem is a native Tizen component.
  • PulseAudio
    • PulseAudio in the Tizen does not support udev.
    • PulseAudio should be started as system mode.
    • To support a variety of devices, some configuration files have been separated from PulseAudio to mmfw-sysconf. [Refer to the Configuration section].
    • Do not change the default sink in /etc/pulse/system.pa. Default sink is used by some modules. If it was changed, there will be problems in sound playback.
      load-module module-remap-sink sink_name=mono_alsa master=alsa_output.0.analog-stereo channels=1
  • asound.conf
    • The name AIF2, AIF3 should not be changed.
    • /etc/asound.conf has a dependency on the hardware. For more detailed information, see how to configure.

Configuration

  • PulseAudio configuration usage
    • To support a variety of devices, some configuration files have been separated from PulseAudio to mmfw-sysconf. PulseAudio has various configuration files:
      • /etc/pulse/client.conf
        • Configuration file for PulseAudio clients. The PulseAudio client library reads configuration directives from a file ~/.pulse/client.conf on startup and when that file doesn't exist, from /etc/pulse/client.conf.
        • The configuration file is a simple collection of variable declarations. If the configuration file parser encounters either ; or #, it ignores the rest of the line until its end.
        • For the settings that take a boolean argument the values true, yes, on and 1 are equivalent, resp. false, on, off and 0.
        • See the man page of pulse-client.conf(5) for more information.
      • /etc/pulse/daemon.conf
        • Configuration file for the PulseAudio daemon. The PulseAudio sound server reads configuration directives from a file ~/.pulse/daemon.conf on startup, and when that file doesn't exist from /etc/pulse/daemon.conf. Note that the server also reads a configuration script on startup default.pa, which also contains runtime configuration directives.
        • The configuration file is a simple collection of variable declarations. If the configuration file parser encounters either ; or # it ignores the rest of the line until its end.
        • For the settings that take a boolean argument the values true, yes, on and 1 are equivalent, resp. false, on, off and 0.
        • See the man page pulse-daemon.conf(5) for more information.
      • /etc/pulse/default.pa
        • PulseAudio Sound Server Startup Script. This startup script is used only if PulseAudio is started per user (that is, not in the system mode). User mode is not recommended in the Tizen. See the system.pa.
        • The PulseAudio sound server interprets the file ~/.pulse/default.pa on startup, and when that file doesn't exist, /etc/pulse/default.pa. It should contain directives in the PulseAudio CLI languages, as documented on http://pulseaudio.org/wiki/CLI.
      • /etc/pulse/system.pa
        • Pulseaudio Sound Server Startup Script. This startup script is used only if PulseAudio is started in system mode.
        • It should contain directives in the PulseAudio CLI languages, as documented on http://pulseaudio.org/wiki/CLI.
      • /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf
        • Default profile definitions for the ALSA backend of PulseAudio. This is used as fallback for all cards that have no special mapping assigned (and should be good enough for the vast majority of cards). ALSA devices are exposed in PulseAudio. An ALSA device string is used to open a device, channel to map and mixer path to use. This is encoded in a 'mapping'. Such multiple mappings can be bound together in a 'profile', which is then directly exposed in the UI as a card profile. Each mapping assigned to a profile will result in one sink/source, to be created if the profile is selected for the card.
      • In addition, there are a few more configuration files. Currently, they do not have a major impact, but can be modified, if necessary.
        • usr/share/pulseaudio/alsa-mixer/profile-sets/
          • native-instruments-audio4dj.conf
          • native-instruments-audio8dj.conf
        • usr/share/pulseaudio/alsa-mixer-paths/
          • analog-input-aux.conf
          • analog-input-fm.conf
          • analog-input-linein.conf
          • analog-input-mic-line.conf
          • analog-input-mic.conf
          • analog-input-mic.conf.common
          • analog-input-tvtuner.conf
          • analog-input-video.conf
          • analog-input.conf
          • analog-input.conf.common
          • analog-output-headphones-2.conf
          • analog-output-headphones.conf
          • analog-output-lfe-on-mono.conf
          • analog-output-mono.conf
          • analog-output-speaker.conf
          • analog-output.conf
          • analog-output.conf.common
  • How to apply and verify modifications
    • To apply modifications, restart pulseaudio:
 
$ kill -9 <PulseAudio PID>
$ /usr/bin/pulseaudio --log-level=4 --system –D 
    • To check that modules were loaded normally, run this:
$ pactl list
      • dump all currently loaded modules, available sinks, sources, streams, etc.
    • The actual recording and playback
      • Check the behavior of the Kernel and ALSA.
 
$ arecord –f <format> -c <channels> -r <rate> <filename>
$ aplay –f <format> -c <channels> -r <rate> <filename>
    • Check the behavior of the PulseAudio.
$ parecord –f <format> -c <channels> -r <rate> <filename>
$ paplay –f <format> -c <channels> -r <rate> --raw <filename>
    • PulseAudio troubleshooting
  • Typically, the default playback and capture device is used hw:0,0. This is set when load-module is detected in system.pa. However, some hardware may need to set a different default device. There are a few ways to solve this problem.
    • Suppose your default device is card 0, device 3. A simple way to modify the /etc/pulse/system.pa file is to disable automatic detection and manually load sink and source modules:
### Alternatively use the static hardware detection module (for systems that
### lack HAL support)
#load-module module-detect
load-module module-alsa-sink device=hw:0,3 name=0.analog-stereo
load-module module-alsa-source device=hw:0,3 name=0.analog-stereo…
.endif
    • Another way is to modify /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf. The device-string is an ALSA device string.
[Mapping analog-stereo]                                             
device-strings = hw:0,3
channel-map = left,right
paths-output = analog-output analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-out
paths-input = analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-inpu
priority = 10
  • asound.conf
    • In this file, some configurations have a dependency on the hardware. Format, channels, and such values can be changed depending on the hardware.
pcm. !default {
        type hw
        card 0
}

ctl. !default {
        type hw
        card 0
}

pcm. AIF2{
        type hw
        card 0
        device 1
        format S16_LE
        channels 2
        rate 8000
}

pcm. AIF3{
        type hw
        card 0
        device 3
}

#LPaudio of C210 not yet implemented
pcm. lpaudio {
        type null
}
    • The name AIF2, AIF3 should not be changed.
    • AIF2 is used for a modem interface
    • AIF3 is used for a bluetooth interface
    • The highlighted parameters for AIF2, AIF3 can be changed by hardware configuration and this should be matched with hardware configuration.

References

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

Player

Player.png

Description

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

Porting OAL Interface

Playerplugin.png

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

Configuration

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

References

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

Codec

Codec.png

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

Description

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

Gstreamer codec plugin.png

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

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

Gst-inspect.png

  • OpenMAX component codec plugin

Openmax.png

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

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

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

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

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

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

Porting OAL Interface

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

Gst-openmax.png

  • If a 3rd party developer needs to develop a decoder plugin on top of OpenMAX IL component & add it to gst-openmax package, one has to follow these steps:
    • Derive video/audio decoder’s object from GstOmxVideoDec/GstOmxAudioDec object
    • Derive video/audio decoder’s object class from GstOmxVideoDecClass/GstOmxAudioDecClass
    • Implement type_base_init () function of decoder’s object:
GstElementClass *element_class;

  element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_details_simple (element_class,
      "OpenMAX IL MPEG-4 video decoder",
      "Codec/Decoder/Video",
      "Decodes video in MPEG-4 format with OpenMAX IL", "Felipe Contreras");
  {
    GstPadTemplate *template;

    template = gst_pad_template_new ("sink", GST_PAD_SINK,
        GST_PAD_ALWAYS, generate_sink_template ());

    gst_element_class_add_pad_template (element_class, template);
  }
    • Implement type_class_init () function of decoder’s object like below:
static void
type_class_init (gpointer g_class, gpointer class_data)
{
  GObjectClass *gobject_class;
  GstOmxBaseFilterClass *basefilter_class;

  gobject_class = G_OBJECT_CLASS (g_class);
  basefilter_class = GST_OMX_BASE_FILTER_CLASS (g_class);

  gobject_class->finalize = finalize;
}
    • Implement type_instance_init() function of decoder’s object like below:
static void
type_instance_init (GTypeInstance * instance, gpointer g_class)
{
  GstOmxBaseVideoDec *omx_base;

  omx_base = GST_OMX_BASE_VIDEODEC (instance);

  omx_base->compression_format = OMX_VIDEO_CodingMPEG4;
}
    • Decoder plugin will get compressed frame in sinkpad’s virtual chain function (that is pad_chain (), which is implemented in GstOmxBaseFilter) and then OpenMax Gstreamer decoder plugin will pass the compressed frame to the respective decoder’s OpenMax-IL component. Refer gst-openmax package for pad_chain() function implementation.
    • GstOmxBaseFilter also has ouput_loop () function implementation, which will be running as a task on source pad of decoder plugin and, once a decoded buffer is available, the same will be pushed to next downstream element (e.g. renderer element). This API will be blocked till OpenMax IL decoder component gives decoded raw buffer. Please refer gst-openmax package for ouput_loop() function implementation.
      • New decoder plugin xxx_get_type() function need to be registered with get_type array of function pointers in gstomx.c file.
      • Also new plugin details need to be registered in gst_openmax.conf file, like other plugins.

Configuration

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

Gst-openmax.conf.png

Example:

Omx mpeg4dec.png

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

Videoencoder.png

References

Connectivity

Bluetooth

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

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

The below figure explains the Bluetooth architecture on Tizen.

Bluetooth Low Energy function was implemented in bluez & bluetooth-frwk. But there is no SDK APIs about BLE functions. We have a plan to include BLE SDK APIs in Tizen 3.0.

Bluetooth.png

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

Description

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

Porting OAL Interface

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

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

Configuration

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

Below is the example of BCM4330 Bluetooth chipset by Broadcomm.
  • hciattach - Project bluez/tools/hciattach.c is patched to enable the BCM4330 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 BCM4330.
  • The Bluetooth UART used is /dev/ttySAC0
  • The Broadcom firmware used is BCM4330B1_002.001.003.0221.0265.hcd
  • The UART speed configuration is 3000000 for BCM4330B1
  • The bcmtool used is bcmtool_4330b1
  • The .bd_addr contains the unique bluetooth address, which is generated during first bluetooth activation
  • How to register the bluetooth device:
   bcmtool_4330b1 /dev/ttySAC0 –FILE=BCM4330B1_002.001.003.0221.0265.hcd –BAUD=3000000 –ADDR=/csa/bluetooth/.bd_addr –SETSCO=0,0,0,0,0,0,0,3,3,0 –LP
  • Attaching a serial device using UART HCI to the bluetooth stack for a broadcom device
   hciattach /dev/ttySAC0 –S 3000000 bcm2035 3000000 flow
  • Running the bluetooth daemon version 4.101
   bluetoothd 
  • Device up and setting up the device name, SSP mode enabling
hciconfig hci0 up
hciconfig hci0 name “Tizen”
hciconfig hci0 sspmode 1
  • Turn on the bluetooth radio
   rfkill unblock bluetooth 
  • Turn off the bluetooth radio
   rfkill block bluetooth

References

Open source components versions : BlueZ 4.101, ObexD 0.48

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

Reference kernel configuration for BT

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

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

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

   CONFIG_INPUT_MISC=y
   CONFIG_INPUT_UINPUT=y

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

   CONFIG_INPUT_GP2A=y
   CONFIG_INPUT_KR3DH=y

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

   CONFIG_BT_SCO=y
   CONFIG_INPUT_GP2A=y
   CONFIG_INPUT_KR3DH=y

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

   CONFIG_BT_SCO=y

WLAN

Description

Wlan.png

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

Feature Overview:

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

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

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

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

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

Porting OAL Interface

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

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

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

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

Turning Wi-Fi ON/OFF:

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

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

Configuration

None

References

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

NFC

Description

Nfc.png

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

Porting OAL Interface

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

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

'onload' function for reference :

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

The NFC OAL interfaces are defined in this structure:

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

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

   int (*init) (net_nfc_oem_controller_init*) ;

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

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


Configuration

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


References

Kernel Config

 Using Pn544 : CONFIG_PN544_NFC
 Using Pn65n : CONFIG_PN65N_NFC

API references available are under the Porting_Guide/Appendix

LINKS

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 libslp_tapi package.
- TAPI executes in application’s context, it provides Sync and Async APIs.
Telephony02.png


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


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/libslp-tapi.git – TAPI
framework/telephony/tel-plugin-dbus_tapi.git – Communicator (DBUS_TAPI)
framework/telephony/tel-plugin-at_standard.git – AT Standard plug-in
framework/telephony/tel-plugin-indicator.git – Free Style plug-in (Indicator)
framework/telephony/tel-plugin-packetservice.git – Free Style plug-in (packetservice)
framework/telephony/tel-plugin-vconf.git – Free Style plug-in (Database)
framework/telephony/tel-plugin-database.git – Free Style plug-in (VCONF)
framework/telephony/tel-plugin-imc.git – Modem plug-in (device)
framework/telephony/tel-plugin-imcmodem.git – Modem Interface plug-in (device)
framework/telephony/tel-plugin-atmodem.git – Modem plug-in (emulator)
framework/telephony/tel-plugin-vmodem.git – Modem Interface plug-in (emulator)

Application

Description

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

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

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

Configuration

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

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

Appendix

NFC OAL API

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

net_nfc_error_e : When it fails, it returns error code.

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

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

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

net_nfc_error_e : When it fails, it returns error code.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Variants
Actions
Navigation
Toolbox