페이지

2013년 7월 2일 화요일

[XMPP] Spark 플러그인 개발하기

1. 들어가기

    XMPP 프로토콜을 지원하는 메시징 클라이언트 Spark는 플러그인 방식으로 새로운 기능을 추가할 수 있도록 한다. 이 문서는 Spark 플러그인을 개발하는 과정을 간략히 정리한 것이다.

2. 개발 환경

    Windows 7 (64-bit)
    JDK 1.6.0_45 (64-bit)
    Ant 1.7.1
    Spark 2.6.3
    Sparkplug Kit 2.0.7

3. Sparkplug Kit 설치

    3.1 다운로드

        아래의 위치에서 Sparkplug Kit 2.0.7을 다운로드한다.

            http://www.igniterealtime.org/builds/sparkplug_kit/sparkplug_kit_2_0_7.zip

    3.2 설치

        압축을 풀고 원하는 위치로 옮긴다.
     
    3.3 sparkplugs\builder\build\build.xml 수정
 
        1) Sparkplug Kit 내에 포함되어 있는 Spark의 API 버전이 낮기 때문에 새로 설치한 Spark 2.6.3을 가리키도록 spark.home 속성의 값을 수정한다.
     
            -    <property name="spark.home" value="${plug.dir}/../spark" />
            +    <property name="spark.home" value="C:\Program Files (x86)\Spark" />
     
        2) javac 태스크의 속성 source와 target의 값이 1.4로 지정되어 있다. 이것을 현재 널리 쓰이고 있는 JDK 버전인 1.6으로 바꾸어 준다. JDK 1.4에서는 generics가 지원되지 않는다.

4. 플러그인 개발

    4.1 플러그인 작성

        단원 "5. 플러그인 작성" 참조.

    4.2 플러그인 빌드
 
        아래와 같이 빌드 명령을 실행하면 sparkplugs\builder\myplugin.jar 파일이 생성될 것이다.

            sparkplugs\builder\build>ant

    4.3 플러그인 설치

        1) sparkplugs\builder\myplugin.jar 파일을 아래 위치로 복사한다.
     
            C:\Program Files (x86)\Spark\plugins
         
        2) Spark를 재시작하고 아래 메뉴를 실행하면 설치한 플러그인들의 목록을 확인할 수 있다.
     
            Spark -> 플러그인

5. 플러그인 작성

    이번 단원에서는 최소한의 파일들만으로 플러그인을 작성해 보았다. 플러그인 작성에 대해 보다 자세히 알아 보고자 한다면 Sparkplug Development Guide를 읽어 보기 바란다.

    5.1 디렉토리 생성

        아래와 같이 하부 디렉토리 구조와 소스 파일을 만든다.

            sparkplugs\builder\src
                com
                    examples
                        plugin
                            MyPlugin.java

    5.2 plugin.xml

        <plugin>
            <name>My Plugin</name>
            <version>1.0</version>
            <author>Your Name</author>
            <homePage>Your Homepage</homePage>
            <email>Your Email Address</email>
            <description>My Plugin Example</description>
            <class>com.examples.plugin.MyPlugin</class>
            <minSparkVersion>2.0.0</minSparkVersion>
        </plugin>

    5.3 MyPlugin.java

        package com.examples.plugin;

        import org.jivesoftware.spark.plugin.Plugin;

        public class MyPlugin implements Plugin {
            /**
             * Called after Spark is loaded to initialize the new plugin.
             */
            public void initialize() {
                System.out.println("Welcome To Spark");
            }

            /**
             * Called when Spark is shutting down to allow for persistence of information
             * or releasing of resources.
             */
            public void shutdown() {

            }

            /**
             * Return true if the Spark can shutdown on users request.
             * @return true if Spark can shutdown on users request.
             */
            public boolean canShutDown() {
                return true;
            }

            /**
            * Is called when a user explicitly asked to uninstall this plugin.
            * The plugin owner is responsible to clean up any resources and
            * remove any components install in Spark.
            */
            public void uninstall(){
               // Remove all resources belonging to this plugin.
            }
        }

6. 참고 자료

    가. Sparkplug Development Guide

2013년 6월 14일 금요일

Windows에 AMP와 MediaWiki 설치하기

1. 들어가기

    AMP는 Apache + MySQL +  Perl/PHP/Python에 대한 줄임말이다. LAMP (Linux + AMP)라고 하여 Linux에 설치하는 것으로 많이 소개하고 있지만 Windows에서도 간편하게 설치하여 사용할 수 있다.
 
    이 글은 Windows 7에 Apache + MySQL + PHP를 설치하고 그 기반에서 MediaWiki를 설치하여 실행하는 과정을 간략히 정리한 것이다.

2. MySQL

    * 버전 5.6.12

    1) 다운로드

        http://dev.mysql.com/downloads/installer/

        MySQL Installer 5.6.12

        Windows (x86, 32-bit), MSI Installer
        (mysql-installer-web-community-5.6.12.0.msi)

    2) 다운로드한 MSI 파일을 더블클릭하여 설치를 진행한다.
 
        설치 위치:
     
            C:\Program Files\MySQL
     
        선택 사항:
         
            Install MySQL Products
            Choosing a Setup Type:
                Developer Default
            MySQL Server Configuration:
                Server Configuration Type
                    Config Type: Developer Machine
                Enable TCP/IP Networking
                    Port Number: 3306
                    Open Firewall port for network access
                Root Account Password
                    MySQL Root Password: ****
                MySQL User Accounts
                    Add User
                        Username: user001
                        Host: <All Hosts (%)>
                        Role: DB Admin
                        Password: ****
                Windows Service Details
                    Windows Service Name: MySQL56

        주의:
     
            위에서 "Host: <All Hosts (%)>" 설정은 MediaWiki 설치를 완료하고 접속하면 DB 계정 관련 에러를 일으키는 원인이 된다. 이에 대해서는 이 글의 마지막 단원 "6. DB 계정 관련 에러"에서 원인과 해결 방법을 제시하고 있다. 애초에 문제를 일으키지 않도록 하려면 아래와 같이 설정하도록 한다.
         
                Host: localhost

    3) Windows 시작 메뉴에서 "MySQL 5.6 Command Line Client"를 실행하고 아래 명령들을 차례대로 수행해 본다.
 
        Enter password: ****
        mysql> show databases;
        mysql> use mysql;
        mysql> show tables;
        mysql> desc user;
        mysql> select host, user, password from user;
        mysql> exit

3. PHP

    * 버전 5.4.16

    1) 다운로드

        http://windows.php.net/download/#php-5.4
     
        VC9 x86 Thread Safe (2013-Jun-05 22:49:25)
        http://windows.php.net/downloads/releases/php-5.4.16-Win32-VC9-x86.zip
 
    2) 다운로한 ZIP 파일을 원하는 위치에 풀어 놓는다.
 
        설치 위치:
     
            C:\DevApps\php
     
    3) 설치한 디렉토리에서 php.ini-development을 php.ini로 복사하고 php.ini 파일을 열어 아래와 같이 수정한다.
 
        extension_dir=C:\DevApps\php\ext
        extension=php_mysql.dll
 
4. Apache

    * 버전 2.2.22

    1) 다운로드
 
        http://apache.mirror.cdnetworks.com//httpd/binaries/win32/
     
        http://apache.mirror.cdnetworks.com//httpd/binaries/win32/httpd-2.2.22-win32-x86-openssl-0.9.8t.msi
     
    2) 다운로드한 MSI 파일을 더블클릭하여 설치를 진행한다.
 
        설치 위치:
     
            C:\Program Files (x86)\Apache Software Foundation\Apache2.2
 
        선택 사항:
     
            Server Information
                Network Domain: localhost
                Server Name: localhost
            Setup Type
                Typical
             
    3) {Apache 설치 디렉토리}/conf/httpd.conf 파일을 열고 아래 항목들을 추가한다.
 
        LoadModule php5_module C:/DevApps/php/php5apache2_2.dll
     
        AddHandler application/x-httpd-php .php
        PHPIniDir C:/DevApps/php

        <IfModule dir_module>
            DirectoryIndex index.html index.php
        </IfModule>

    4) PHP와 MySQL 연결을 테스트하기 위하여 아래 파일을 작성한다.

        {Apache 설치 디렉토리}/htdocs/phpinfo.php
     
            <?php
            mysql_connect('localhost', 'user001', 'your_password');
            phpinfo();
            ?>
         
    5) Apache를 재시작한 다음 브라우져로 아래 주소에 연결한다.
 
        http://localhost/phpinfo.php
     
        여러 종류의 정보를 나타내는 테이블들이 나타나고 mysql 정보를 표시하는 테이블에서 Active Links의 값이 1이면 PHP 페이지에서 MySQL 연결이 정상적으로 동작하는 것이다.
     
    6) 흔히 발생할 수 있는 몇 가지 예외 상황과 그에 대한 점검 사항을 아래에 적어 보았다.

        만약 PHP 구문이 그대로 표시된다면 httpd.conf에서 PHP 설치 경로가 잘못 지정되었을 가능성이 높다. 그렇다면 경로를 제대로 지정하고 Apache를 재시작하여 테스트를 해 본다.
     
        mysql_connect 구문이 정의되지 않았다는 에러 메시지가 페이지에 표시되면 php.ini 파일에서 지정한 extension_dir 경로를 통해서 php_mysql.dll을 찾을 수 없기 때문일 것이다.
     
        mysql_connect 실행 부분에서 사용자 계정으로 접근이 거부되었다는 경고 메시지가 페이지에 뜨면 지정한 계정의 사용자 이름과 암호가 올바른지 확인해 본다.

5. MediaWiki

    * 버전 1.21.1

    1) 다운로드
 
        http://www.mediawiki.org/wiki/Download
     
        http://download.wikimedia.org/mediawiki/1.21/mediawiki-1.21.1.tar.gz
     
    2) 요구 사항
 
        Web server such as Apache or IIS
        PHP version 5.3.2 or later
            Perl Compatible Reqular Expressions
                - Beginning with PHP 4.2.0 these functions are enabled by default.
                - The Windows version of PHP has built-in support for this extension.
         
            Standard PHP Library
                - This extension is available and compiled by default in PHP 5.0.0.
        Database Server
            MySQL 5.0.2 or later
            or PostgreSQL 8.1 or later
            or SQLite
 
    3) 다운로드한 파일의 압축을 풀고 아래 위치로 옮긴다.
 
        {Apache 설치 디렉토리}/htdocs/wiki
     
    4) 브라우져를 열고 아래 URL로 접속한다. 그러면 설정을 시작하기 위한 페이지를 보여 줄 것이다.
 
        http://localhost/wiki
     
        언어
     
            설치 언어: ko - 한국어
            위키 언어: ko - 한국어
         
        사용 환경 검사
     
            이 환경이 미디어위키 설치에 적합한지 기본 검사를 실행합니다. 설치 중 도움이 필요하다면 이 검사 결과를 함께 제공해주어야 합니다.
            PHP 5.4.16(이)가 설치되었습니다.
            경고: APC, XCache 또는 WinCache를 찾을 수 없습니다.
            개체 캐싱을 활성화하지 않습니다.
            GNU diff3를 찾을 수 없습니다.
            GD 라이브러리나 ImageMagick를 찾을 수 없습니다.
            그림 섬네일이 비활성화됩니다.
            "http://localhost"(을)를 서버 이름으로 사용합니다.
            "http://localhost/wiki"(을)를 서버 URL로 사용합니다.
            경고: 유니코드 정규화를 처리할 intl PECL 확장 기능을 사용할 수 없기 때문에 느린 순수한 PHP 구현을 대신 사용합니다.
            높은 트래픽 사이트에서 실행하려면 유니코드 정규화를 읽어보시기 바랍니다.
            환경이 확인되었습니다. 미디어위키를 설치할 수 있습니다.

        데이터베이스에 연결
     
            데이터베이스 종류: MySQL
            MySQL 설정
                데이터베이스 호스트: localhost
                이 위키 식별
                    데이터베이스 이름: my_wiki
                    데이터베이스 테이블 접두어:
                설치를 위한 사용자 계정
                    데이터베이스 사용자 이름: root
                    데이터베이스 비밀번호: ****

        데이터베이스 설정
         
            웹 접근을 위한 데이터베이스 계정
                데이터베이스 사용자 이름: user001
                데이터베이스 비밀번호: ****
            스토리지 엔진: InnoDB
            데이터베이스 문자 집합: 바이너리
         
        이름
     
            위키 이름: Mercury
         
            프로젝트 이름공간:
                위키 이름과 같은 이름: Mercury
         
            관리자 계정
                사용자 이름: your_wiki_admin
                비밀번호: ****
             
        설정
     
            사용자 권한 프로필:
                열린 위키
            저작권 및 라이선스:
                라이선스 바닥글 없음
             
        설치
     
        완료

            LocalSettings.php를 다운로드하고 아래 위치로 복사한다.
                {Apache 설치 디렉토리}/htdocs/wiki/LocalSettings.php
            브라우져를 열고 아래 URL로 접속하면 Wiki 페이지로 들어간다.
                http://localhost/wiki
         
6. DB 계정 관련 에러

    1) MediaWiki 설치 완료하고 나서 브라우져로 아래 URL에 접속했더니 user001 계정으로 DB 접근이 거부되었다고 한다.
 
        http://localhost/wiki
     
    2) mysql 콘솔로 사용자 테이블을 살펴 보았다.
 
        C:\Users\Admin>"C:\Program Files\MySQL\MySQL Server 5.6\bin\mysql" -u root -p
        Enter password: *******
     
        mysql> show databases;
        mysql> use mysql;
        mysql> show tables;
        mysql> desc user;
        mysql> select host, user, password from user;
        +-----------+---------+-------------------------------------------+
        | host      | user    | password                                  |
        +-----------+---------+-------------------------------------------+
        | localhost | root    | *98CE4C1372B6A23FF1F0E71197948882FF18145E |
        | 127.0.0.1 | root    | *98CE4C1372B6A23FF1F0E71197948882FF18145E |
        | ::1       | root    | *98CE4C1372B6A23FF1F0E71197948882FF18145E |
        | %         | user001 | *98CE4C1372B6A23FF1F0E71197948882FF18145E |
        | localhost | user001 |                                           |
        +-----------+---------+-------------------------------------------+
        5 rows in set (0.00 sec)
     
    3) 문제의 원인과 해결 방법은 아래와 같다.
 
        원인:
     
            MySQL 설치 과정에서 All Hosts (%)를 대상으로 하여 user001을 추가하였다. 하지만 MediaWiki는 설치 도중 "웹 접근을 위한 데이터베이스 계정" 항목에서 지정한 user001에 대하여 localhost를 대상으로 한다고 간주하고 동일한 MySQL 계정이 없으니 새로 추가했다. 하지만 그 계정의 암호가 지정되어 있지 않다. 또한 localhost를 대상으로 추가된 user001에게는 select, delete, update, insert 등에 대한 권한도 주어지지 않았다는 것을 알 수 있다.
 
        해결:
     
            MySQL Workbench 프로그램을 실행해서 user001@localhost에 대한 암호와 권한을 설정해 준다. 또는 localhost를 대상으로 하는 user001 계정을 지우고 모든 호스트를 대상으로 하는 user0001 계정의 아래 설정 값을 localhost로 바꾸어 준다.
         
                Limit Connectivity to Hosts Matching: localhost
 

2013년 5월 31일 금요일

Cygwin에서 홈 디렉토리의 위치

이상한 일이다. 어제 내 PC의 Cygwin bash shell에서 개발서버에 좀 더 편하게 접속하기 위하여 암호를 입력하지 않는 방식으로 ssh를 사용하여 서버에 로그인할 수 있도록 설정하였다. 그런데 오늘 출근해서 다시 서버에 로그인하려고 하니 암호를 입력하라고 묻는다. 그래서 혹시 서버에서 public key를 저장해 놓는 authorized_keys 파일에 어떤 변경이 가해졌는지 살펴 보았더니 이상이 없다. 이번에는 내 PC에 저장해 놓은 key pair가 정상인지 확인해 보기 위하여 아래와 같은 명령을 실행해 보았다.

  $ cd .ssh
  $ ls -l

어라! 어제 ssh-keygen으로 생성해 놓았던 key pair가 보이지 않는다. 이게 어찌된 일인가? 정상이라면 다음 두 개의 파일이 있어야 한다.

  id_rsa
  id_rsa.pub

나중에 발견하게 된 일이지만, 특이하게도 Cygwin bash shell을 실행할 때 사용자의 홈 디렉토리 위치가 일정하지 않았다. 이를 확인해 보기 위하여 다음과 같은 순서로 bash shell을 실행해 보자. 참고로 내 PC의 환경은 아래와 같다.

  Cygwin 설치 디렉토리 - C:\Apps\cygwin
  Windows 사용자 홈 디렉토리 - D:\Profiles\myid

1) 시스템에서 첫번째 bash 프로세스가 실행될 때에는 아래 위치를 사용자의 홈 디렉토리로 사용한다.

  C:\Apps\cygwin\home\myid

2) 이번에는 다른 DOS창을 열어서 bash shell을 실행해 보았다. 이것은 두 번째의 bash 프로세스를 생성하는 것이다. 이 bash shell은 아래 디렉토리를 홈 디렉토리로 사용한다.

  D:\Profiles\myid

3) 계속해서 bash shell을 실행하고 홈 디렉토리를 확인해 보면 2)번의 결과와 같음을 알 수 있다.

4) 현재 실행중인 모든 bash shell을 닫고 1) ~ 3)의 과정을 실행하면 동일한 현상이 발생한다.

결국 내가 생성해 놓았던 key pair는 Windows 사용자 홈 디렉토리 아래의 .ssh 디렉토리에 있었던 것이다. 당연하게도 첫번째로 실행된 bash shell을 제외한 다른 bash shell에서는 암호 입력 과정 없이 서버에 로그인할 수 있었다.

Cygwin에서 왜 첫번째 bash shell의 홈 디렉토리가 이후에 실행된 bash shell의 홈 디렉토리와 다른지에 대해서는 관련 내용을 찾을 수 없었지만 이 문제를 간단하게 해결할 수 있는 방법으로 아래 두 가지가 있다.

1. /etc/fstab 파일을 열고 아래와 같이 한 줄을 추가하여 Windows 사용자 홈 디렉토리의 상위 디렉토리를 /home으로 마운트한다. 이렇게 하면 Cygwin bash shell 입장에서는 Windows 경로 C:\Apps\cygwin\home/myid이 D:\Profiles/myid를 가리키는 것이 된다.

  D:/Profiles /home ntfs binary 0 0

2. /etc/passwd 파일에서 사용자의 홈 디렉토리를 Windows 사용자 홈 디렉토리로 지정한다.

    ....:/cygdrive/d/Profiles/myid:...


2013년 5월 28일 화요일

[BLE] 저전력 블루투스 이해 - 프러파일, 서비스, 특성, 속성

1. 들어가기

저전력 블루투스를 응용하여 애플리케이션을 개발하고자 한다면 소프트웨어 개발자 입장에서 꼭 이해해야 할 용어들이 있다. 그 중에 네 가지를 꼽으라면 아래와 같다.

    1) 프러파일 (profile)
    2) 서비스 (service)
    3) 특성 (characteristic)
    4) 속성 (attribute)

특성과 속성은 영문이나 우리말로 번역한 것이나 어감이 다소 어색하고 의미가 모호하게 느껴지지만, 자주 사용하다 보면 익숙해질 것이다. 이해를 돕기 위하여 정확히 일치하지는 않지만 명절 때 주고 받는 종합선물세트에 비유해 보았다.

    1) 프러파일 명세서는 상품 목록과 소개서이다. 주문을 통해서 받는 대상이 아니라 잠재적인 구매자에게 제공하는 정보이다.
    2) 서비스 명세서는 종합선물세트의 내용물을 규정한다. 서비스는 종합선물세트이다.
    3) 특성은 종합선물세트에 담긴 물품이고, 구매자가 실제로 이용하는 것이다.
    4) 속성은 각각의 물품을 놓을 수 있는 틀이다.

이제 건강 온도 프러파일(Health Thermometer Profile)을 가지고 각각의 용어들이 구체적으로 무엇을 의미하는지, 그리고 서로 어떤 관계를 가지는지 설명해 보고자 한다.

2. 프러파일 (profile)

프러파일 명세서는 어떤 서비스들을 제공할 것인지를 규정하는 문서이다. 건강 온도 프러파일은 아래 두 가지 서비스를 제공하도록 규정하고 있다.

    Health Thermometer Service
    Device Information Service

여기서 주목할 것은 프러파일은 실제로 제공되는 것이 아니기 때문에 연결하는 상대편 장치의 입장에서 보면 프러파일이란 실체는 없는 것이다.

3. 서비스 (service)

서비스 명세서가 규정하고 있는 서비스, 그리고 서비스의 내용물인 특성은 속성이라는 틀을 사용해서 제공된다.

서비스에 대한 정의는 서비스에 대한 선언과 여러 개의 특성에 대한 정의로 이루어진다. 서비스의 정의가 끝나는 부분을 따로 표시하지 않기 때문에 다음 서비스 선언을 만나거나 더 이상 서비스 정의가 존재하지 않으면 끝이라고 간주한다.

    서비스의 선언 (서비스의 유형)
    특성의 정의
    특성의 정의
    ...

Health Thermometer Service의 경우 서비스를 선언하는 부분은 0x1809라는 값을 가지고 있는데, 이것이 Health Thermometer Service임을 나타내는 ID이다. 이어서 아래와 같이 네 개의 특성들을 정의하고 있다.

    Temperature Measurement
    Client Characteristic Configuration descriptor

    Temperature Type

    Immediate Temperature
    Client Characteristic Configuration descriptor

    Measurement Interval
    Client Characteristic Configuration descriptor
    Valid Range descriptor

4. 특성 (characteristic)

하나의 특성은 여러 가지 정보들과 값으로 정의되고 각각의 정보를 담기 위해서 속성 하나씩을 필요로 한다. 특성 하나는 여러 개의 연속된 속성을 사용한다.

    특성의 선언 (성질, 특성의 유형)
    특성의 값
    특성에 대한 묘사 (설정)
    특성에 대한 묘사 (설명)
    ...

5. 속성 (attribute)

하나의 속성은 네 개의 구성 요소로 이루어지며 순서대로 다음과 같은 의미를 가진다.

    Handle - 속성의 주소
    Type - 속성의 유형
    Value - 속성의 값
    Permissions - 속성에 대한 접근 권한

그래서 속성 테이블은 가로로 네 개의 열을 가지고 세로로 길게 이어지는 형태로 무언가를 담을 수 있는 틀이라고 볼 수 있다. 이 틀 자체에 대한 명세서가 Attribute Protocol(ATT)이고 이 틀을 사용하여 서비스를 제공하는 방법에 대한 명세서가 Generic Attribute Profile(GATT)이다.

6. 결론

    1) 속성은 저장 공간이며 테이블 구조를 가진다.
    2) 특성은 의미 있는 정보와 그것에 대한 설정, 또는 설명으로 이루어진다.
    3) 서비스는 특성들의 모음을 제공하고 연속적으로 이어져 있는 속성들을 저장 공간으로 사용한다.
    4) 프러파일은 제공해야 할 서비스들의 목록을 규정하는 명세서이다.

2013년 5월 21일 화요일

[XMPP] Openfire 플러그인 개발하기

1. 들어가기

    Openfire는 XMPP 프로토콜을 지원하는 메시징 서버이다. 그리고 새로운 기능을 추가하고 Admin Console에 UI를 추가할 수 있도록 플러그인 방식을 지원하고 있다. 이 문서는 Openfire를 리눅스 서버에 설치해서 실행하고 윈도우 환경에서 플러그인을 개발하는 과정을 간략히 정리한 것이다.

2. 개발 및 운영 환경

    2.1 개발 환경

        Windows 7 (64-bit)
        JDK 1.6.0_45 (64-bit)
        Ant 1.7.1
        Openfire 3.8.1 소스

    2.2 운영 환경

        Ubuntu 12.04 LTS (64-bit)
        JDK 1.6.0_45 (64-bit)
        Openfire 3.8.1

3. Openfire 설치 및 실행

    3.1 다운로드

        아래의 위치에서 Openfire 3.8.1을 다운로드한다.

            http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_3_8_1.tar.gz

    3.2 설치

        아래와 같이 압축을 풀고 원하는 위치로 옮긴다.

            $ tar -xzvf openfire_3_8_1.tar.gz
            $ mv openfire /opt

    3.3 실행

        아래의 명령으로 Openfire를 실행한다.

            $ /opt/openfire/bin/openfire start

    3.4 서버 설정 및 Admin Console 접속

        브라우져를 열고 아래의 URL 주소로 접속하면 서버 설정 과정을 거치게 된다. 설정이 끝나면 Admin Console 화면이 나타난다.

            http://<host_address>:9090

4. 플러그인 개발

    4.1 Openfire 3.8.1 소스 다운로드

        http://www.igniterealtime.org/downloads/source.jsp

    4.2 전체 플러그인 빌드

        $ ant plugins

    4.3 플러그인 작성

        단원 "5. 플러그인 작성" 참조.

    4.4 하나의 플러그인 빌드

        $ ant -Dplugin=<pluginName> plugin

    4.5 플러그인 설치

        1) Admin Console의 Plugins 탭으로 이동한다.

        2) "파일 선택" 버튼을 눌러 아래의 위치에서 설치하고자 하는 플러그인 파일을 선택한다.

            openfire_src\target\openfire\plugins

        3) "Upload Plugin" 버튼을 누른다.

5. 플러그인 작성

    이번 단원에서는 최소한의 파일들만으로 플러그인을 작성해 보았다. 플러그인 작성에 대해 보다 자세히 알아 보고자 한다면 Openfire Plugin Developer Guide를 읽어 보기 바란다.

    5.1 디렉토리 생성

        1) 다음 위치에 helloWorld 디렉토리를 만든다.

            openfire_src\src\plugins

        2) 아래와 같이 하부 디렉토리 구조와 파일을 만든다.

            helloWorld
                src
                    java
                        com
                            myplugin
                                hello
                                    HelloWorldPlugin.java
                    web
                        index.html
                plugin.xml

    5.2 plugin.xml

        <?xml version="1.0" encoding="UTF-8"?>
        <plugin>
            <class>com.myplugin.hello.HelloWorldPlugin</class>
            <name>HelloWorld</name>
            <description>HelloWorld plugin</description>
            <author>trvoid</author>
            <version>1.0</version>
            <date>05/16/2013</date>
            <url>http://trvoid.blogspot.com</url>
            <minServerVersion>3.0.0</minServerVersion>
            <licenseType>internal</licenseType>

            <adminconsole>
                <tab id="tab-helloworld" name="HelloWorld"
                        description="Click to manage HelloWorld">
                    <sidebar id="sidebar-hello-config" name="Configuration">
                        <item id="hello-intro" name="Introduction"
                                url="index.html"
                                description="Click to view Introduction"/>
                    </sidebar>
                </tab>
            </adminconsole>
        </plugin>

    5.3 HelloWorldPlugin.java

        package com.myplugin.hello;

        import org.jivesoftware.openfire.container.Plugin;
        import org.jivesoftware.openfire.container.PluginManager;

        import java.io.File;

        public class HelloWorldPlugin implements Plugin {
            public void initializePlugin(PluginManager manager, File pluginDirectory) {
             
            }

            public void destroyPlugin() {
             
            }
        }

    5.4 index.html

        <html>
            <head>
                <title>HelloWorld</title>
                <meta name="pageID" content="hello-intro"/>
            </head>
            <body>
                <h1>Hello World!</h1>
            </body>
        </html>

6. 참고 자료

    가. Installation Guide
    나. Openfire Plugin Developer Guide

2013년 5월 13일 월요일

[BLE] TI CC2540 Mini DK 사용하기 - JavaSimplePeripheral 프로그램


1. 들어가기

    USB 동글과 KeyFob이 서로 연결되어 있는 상태에서 PC 프로그램인 JavaSimplePeripheral을 사용하여 다음 두 가지를 테스트해 보았다.
 
        1) KeyFob의 단추 누름 상태를 Notification 방식으로 전송하도록 JavaSimplePeripheral이 KeyFob의 설정을 변경한다.
        2) JavaSimplePeripheral은 KeyFob의 단추 누름 상태를 전송받아서 화면에 표시한다.

2. 이미지 다운로드

    USB 동글에는 HostTestRelease 이미지, 그리고 KeyFob에는 SimpleBLEPeripheral 이미지를 SmartRF Flash Programmer 프로그램을 이용하여 각각 다운로드한다. HostTestRelease는 외부 장치로부터 HCI 명령을 전달받아서 실행하고, 이벤트나 응답을 외부 장치로 전달하는 역할을 수행한다. SimpleBLEPeripheral은 Simple Keys Service를 구현하고 있다.

    2.1 USB 동글용 프로젝트 및 이미지 위치
 
        프로젝트:
         
            BLE-CC254x-1.3\Projects\ble\HostTestApp\CC2540\HostTestRelease.eww
         
        이미지:
     
            BLE-CC254x-1.3\Accessories\HexFiles\CC2540_USBdongle_HostTestRelease_All.hex

    2.2 KeyFob용 프로젝트 및 이미지 위치
 
        프로젝트:
         
            BLE-CC254x-1.3\Projects\ble\SimpleBLEPeripheral\CC2540DB\SimpleBLEPeripheral.eww

        이미지:
     
            BLE-CC254x-1.3\Accessories\HexFiles\CC2540_keyfob_SimpleBLEPeripheral.hex
     
3. BTool로 테스트하기

    BTool을 사용하여 USB 동글과 KeyFob을 서로 연결하고 Simple Keys Service에 대한 attribute 테이블을 파악한 다음 Client Characteristic Configuration descriptor의 값을 Notification으로 설정한다.

    3.1 장치 발견 및 연결

        1) USB 동글을 PC에 연결한다. 장치 관리자에서 USB 동글의 포트 번호를 확인한다.
        2) BTool을 실행한다. 직렬포트 설정 대화 상자에서 USB 동글의 포트 번호를 지정한다. 다른 항목은 기본으로 설정된 값을 사용한다.
        3) KeyFob의 오른쪽 버튼(B3)을 눌러 Discoverable 모드로 진입한다.
        4) BTool의 Discover/Connect 탭에서 장치 발견 및 연결을 실행한다.
            - 'Discovery' 섹션의 'Scan' 버튼을 누른다. 잠시 후 "Devices Found"의 값이 1로 바뀌는 것을 확인한다.
            - 'Link Control' 섹션의 Slave BDA에서 발견된 장치의 주소를 선택하고 'Establish' 버튼을 누른다. 왼쪽 패널에 "Connection info" 항목이 추가되는 것을 확인한다.

    3.2 Simple Keys Service
 
        Simple Keys Service에 대한 UUID는 0xFFE0이고, BTool의 Adv.Commands 탭에서 GATT_DiscAllCharDesc 명령을 실행하면 아래와 같은 attribute 테이블을 얻을 수 있다.
     
            Handle  Type    Value               Permissions     Notes
            0x0034  0x2800  E0:FF               Read            Start of Simple Keys Service
            0x0035  0x2803  10:36:00:E1:FF      Read            Key Press State characteristic declaration
            0x0036  0xFFE1  00                  (none)          Key Press State characteristic value
            0x0037  0x2902  00:00               Read/Write      Key Press State characteristic configuration
            0x0038  0x2901  "Key Press State"   Read            Key Press State characteristic user description
     
    3.3 Notification 설정하기
 
        BTool의 Read/Write 탭을 열고 Characteristic Write 영역에서 핸들과 값을 아래와 같이 지정한 후 Write 버튼을 누른다.

            핸들: 0x0037
            값: 01:00
 
    3.4 테스트
 
        KeyFob의 왼쪽, 오른쪽 단추를 눌러 가면서 BTool의 로그창에 표시되는 값을 확인한다.
     
            0: 단추 누르지 않음
            1: 왼쪽 단추 누름
            2: 오른쪽 단추 누름
            3: 왼쪽, 오른쪽 단추 동시에 누름
 
4. JavaSimplePeripheral으로 테스트하기

    4.1 다운로드 위치
 
        http://processors.wiki.ti.com/index.php/Category:JavaSimplePeripheral
     
    4.2 eclipse 프로젝트로 import
 
        1) Select an import source:
            General - Existing Projects into Workspace
         
        2) Select root directory: <Location of the extracted JavaSimplePeripheral>
            Copy projects into workspace: Checked
 
    4.3 빌드 문제 수정
 
        프로젝트의 Build Path 설정을 보면 Libraries로 아래 네 가지 항목이 포함되어 있을 것이다. 이 중에서  RXTXcomm.jar만 남기고 나머지 세 개는 제거한다.
     
            RXTXcomm.jar
            rxtxParalle.dll
            rxtxSerial.dll
            SoftNetConsultUtils.2.01.slim.jar
 
    4.4 라이브러리 복사
 
        프로젝트 lib 디렉토리에 있는 세 개의 파일을 아래의 위치로 복사한다.
     
            %JAVA_HOME%\bin\rxtxParallel.dll
            %JAVA_HOME%\bin\rxtxSerial.dll
            %JAVA_HOME%\lib\ext\RXTXcomm.jar
     
    4.5 실행시 링크 에러 수정
 
        프로젝트에 포함되어 있는 RXTX 라이브러리는 32비트 버전인데, 64비트 JDK를 사용하고 있다면 링크 에러가 발생할 것이다.
     
            java.lang.UnsatisfiedLinkError: C:\Program Files\Java\jdk1.7.0_06\bin\rxtxSerial.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform thrown while loading gnu.io.RXTXCommDriver
     
        아래의 위치에서 64비트용 RXTX 라이브러리를 다운로드하여 설치한다.
     
            http://www.cloudhopper.com/opensource/rxtx/
         
    4.6 소스 코드 수정
 
        JavaSimplePeripheral을 실행하여 COM 포트를 지정하고 Connect 단추를 누르면 다음 세 가지 작업을 순차적으로 수행할 것이다.
     
            KeyFob 찾기
            KeyFob에 연결하기
            Key Press State에 대하여 Notification 설정하기
         
        만약 아래와 같은 메시지가 출력된다면 COM 포트를 제대로 지정했는지 확인해 보고, 이상이 없다면 KeyFob의 오른쪽 버튼(B3)을 눌러 Discoverable 모드로 진입하게 한 다음 다시 Connect 버튼을 눌러 본다.
     
            Error connecting to the device.
            Remove and insert again the USB dongle from the USB slot, restart the
             application and try again.
     
        KeyFob을 찾을 수 있었다면 다음과 같은 메시지를 출력할 것이다.
     
            Device found
            Enabling Key Notifications start:
            Enabling Key Notifications end:
 
        그럼에도 불구하고 Key Notify ON / Key Notify OFF 두 개의 단추가 활성화 되지 않는다면 아래 두 군데서 Key Press State characteristic configuration에 접근하기 위한 핸들값을 BTool을 통하여 파악한 값으로 바꾸어 준다.
     
            출력 버퍼의 9번째 바이트: 0x0020 ==> 0x0037
 
            < ConnectionManager.java >
     
                public void simpleKeysEnabler() {
                    System.out.println("Enable Keys \n");
                    //int[] outputBuffer ={ 0x01, 0x12, 0xfd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00 };
                    int[] outputBuffer ={ 0x01, 0x12, 0xfd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x01, 0x00 };
                    new SerialWriter(this.sp,outputBuffer).write();
                }

                public void simpleKeysDisabler() {
                    System.out.println("Disable Keys\n");
                    //int[] outputBuffer ={ 0x01, 0x12, 0xfd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 };
                    int[] outputBuffer ={ 0x01, 0x12, 0xfd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00 };
                    new SerialWriter(this.sp,outputBuffer).write();
                }
         
    4.7 테스트
 
        KeyFob의 왼쪽, 오른쪽 단추를 눌러 가면서 eclipse의 Console 창에 표시되는 값을 확인한다.
     
            0: 단추 누르지 않음
            1: 왼쪽 단추 누름
            2: 오른쪽 단추 누름
            3: 왼쪽, 오른쪽 단추 동시에 누름
 
부록. 참고 자료

    1. 문서

        가. Bluetooth Low Energy CC2540/41 Mini Development Kit User's Guide (http://www.ti.com/litv/pdf/swru270c)
            5.3 Using SmartRF Flash Programmer Software
        나. CC2540/41 Bluetooth Low Energy Software Developer's Guide (http://www.ti.com/lit/pdf/swru271)
            4.3 SimpleBLEPeripheral Sample Project
            4.5 HostTestRelease Network Processor Project
        다. TI BLE Vendor Specific HCI Reference Guide
            BLE-CC254X-1.3\Documents\TI_BLE_Vendor_Specific_HCI_Guide.pdf

    2. 소프트웨어

        가. Bluetooth low energy software stack and tools 1.3 (www.ti.com/blestack)
            - 예제 애플리케이션과 BTool을 포함하고 있다.
        나. SmartRF Flash Programmer 1.12.6 (www.ti.com/tool/flash-programmer)

2013년 5월 12일 일요일

[Java] 자바 직렬 통신 개발 환경

1. 들어가기

    64비트 Windows 7 운영체제에서 자바로 직렬 통신을 할 수 있는 환경에 대하여 조사해 보았다. Java Communications API 2.0에 대한 오라클 구현과 gnu.io.*을 패키지명으로 사용하는 RXTX 구현을 비교해 보았는데, 다음과 같은 이유로 오라클 구현보다 RXTX 구현을 사용하는 것이 바람직하다.
    
        오라클 구현은 OS 지원 대상이 제한적이고, 64비트 바이너리를 제공하지 않으며, 무엇보다도 업데이트가 멎은 듯하다.
        
2. Oracle 구현 사용 방법
        
    Java Communications API 3.0에 대한 오라클 구현이 지원하는 OS는 아래와 같은데, Windows 버전을 제공하지 않으므로 2.0버전을 사용해야 한다.
    
        Solaris SPARC
        Solaris x86
        Linux x86

    2.1 JDK 설치
    
        64비트 JDK에서는 오라클 구현이 제공하는 win32com.dll을 사용하지 못하므로 32비트 JDK를 설치해야 한다.
        
            설치 파일: Windows x86를 위한 jdk-7-windows-i586.exe

    2.2 환경 변수 설정

        java.exe 파일이 다른 경로에, 특히 Windows system32 폴더 아래에 이미 설치되어 있을 수 있다. 앞에서 설치한 JDK의 java.exe를 사용하기 위하여 기존 PATH 변수의 앞쪽에 bin 경로를 추가해 준다.

            > set JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0
            > set PATH=%JAVA_HOME%\bin;%PATH%

    2.3 오라클 구현 설치

        Java Communications API는 JDK 확장 패키지이므로 별도로 오라클 구현을 다운로드 받아서 세 개의 파일을 아래 경로로 복사한다.
        
            https://jspoorloos.googlecode.com/files/javacomm20-win32.zip

            %JAVA_HOME%\bin\win32com.dll
            %JAVA_HOME%\\jre\lib\javax.com.properties
            %JAVA_HOME%\\jre\lib\ext\comm.jar
            
    2.4 SimpleRead 예제 수정

        Java Communications API에 포함되어 있는 예제 SimpleRead.java 를 사용하기 위하여 포트 이름과 파라미터를 자신의 환경에 맞게 수정한다.
        
            public static void main(String[] args) {
                ...
                //if (portId.getName().equals("/dev/term/a")) {
                if (portId.getName().equals("COM4")) {
                    SimpleRead reader = new SimpleRead();
                }
                ...
            }
            
            public SimpleRead() {
                ...
                //serialPort.setSerialPortParams(9600,            
                serialPort.setSerialPortParams(115200,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
                ...
            }
            
    2.5 SimpleRead 컴파일 및 실행

        아래의 명령을 실행하면 장치에서 출력하는 메세지를 화면에 보여 줄 것이다.

            > javac SimpleRead.java
            > java SimpleRead

3. RXTX 구현 사용 방법


    3.1 RXTX 구현 설치

        RXTX는 32비트, 64비트 모두 지원하므로 사용하는 JDK에 따라 아래의 위치에서 원하는 버전을 찾을 수 있다.
    
            RXTX 32비트 버전: http://rxtx.qbang.org/wiki/index.php/Download
            RXTX 64비트 버전: http://www.cloudhopper.com/opensource/rxtx/
            
        RXTX 구현을 다운로드 받아서 세 개의 파일을 다음 경로로 복사한다.
        
            %JAVA_HOME%\bin\rxtxParallel.dll
            %JAVA_HOME%\bin\rxtxSerial.dll
            %JAVA_HOME%\lib\ext\RXTXcomm.jar

2013년 5월 7일 화요일

[BLE] TI CC2540 Mini DK 사용하기 - Notifications


1. 들어가기

    KeyFob과 USB 동글이 서로 연결을 맺고 있다. KeyFob이 어떤 상태를 감지하고 나서 USB 동글 쪽으로 데이터를 보내는 방법에는 두 가지가 있다.
 
        Notifications
        Indications

    Notification은 보내고 나서 수신 확인을 하지 않는 것이고, Indication은 보내고 나서 수신자로부터 확인을 받는 것이다. KeyFob에서 가속도의 변화를 감지할 때마다 USB 동글 쪽으로 가속도 값을 보내는 상황에서는 어느 방식이 더 적합할까? 대개의 경우 시간에 따른 가속도 값의 변화 추이를 살펴 보는 것이 완벽한 수신율을 보장하는 것보다 더 중요하기 때문에 수신 확인을 받을 필요가 없는 Notification이 Indication을 사용하는 것보다 적합할 것이다.
 
    그렇다면 KeyFob이 제공하는 characteristic 중에서 Notification 방식으로 보내는 것이 무엇인지 어떻게 알 수 있는가? 그리고 그 값을 Notification 방식으로 보내도록 하려면 어떻게 해야 하는가? KeyFob은 현재 KeyFobDemo 애플리케이션을 실행하고 있는 중이다.

2. 가속도 측정 및 전송

    KeyFobDemo 애플리케이션이 제공하고 있는 가속도계 서비스는 블루투스 SIG 표준이 아니라 TI에서 예제로 구현한 것이다. 아래 문서의 Figure 27에서 가속도계 서비스에 대한 attribute 테이블을 찾을 수 있다.

        Bluetooth Low Energy CC2540/41 Mini Development Kit User's Guide (http://www.ti.com/litv/pdf/swru270c)

    2.1 가속도계 구동

        Figure 27에서 가속도계를 구동시키는 것과 관련된 characteristic은 아래 두 줄의 attribute로 정의되어 있다.
     
            Handle  Type        Value               Permissions
            0x33    0x2803      0A 34 00 A1 FF      Read    
            0x34    0xFFA1      00                  Read/Write
     
        위의 테이블에서 각 줄의 attribute 유형이 의미하는 바는 다음과 같다.
     
            0x2803      하나의 characteristic을 선언하는 attribute이다.
            0xFFA1      가속도계 구동을 결정하는 값을 담고 있는 attribute이다.
                 
        characteristic을 선언하고 있는 attribute의 값이 의미하는 바를 살펴 보도록 하자.
     
            0x0A        - characteristic의 값에 대하여 읽기(0x02)와 쓰기(0x08)를 할 수 있다.
            0x0034      - characteristic의 값은 핸들 0x0034로 접근할 수 있다.
            0xFFA1      - characteristic의 값은 가속도계 구동을 결정하는 것이다.
                 
        따라서 가속도계를 구동시키려면 BTool의 Characteristic Write 영역에서 아래와 같이 지정하고 Write 버튼을 누르면 된다.
     
            Characteristic Value Handle: 0x0034
            Value: 01:00

    2.2 가속도계의 X-축 값 전송 시작
 
        Figure 27에서 가속도계의 X-축 값과 관련된 characteristic은 아래 네 줄의 attribute로 정의되어 있다.
     
            Handle  Type        Value                   Permissions
            0x39    0x2803      10 3A 00 A3 FF          Read    
            0x3A    0xFFA3      00 00                   (none)  
            0x3B    0x2902      00 00                   Read/Write
            0x3C    0x2901      "Accel X-Coordinate"    Read    
 
        위의 테이블에서 각 줄의 attribute 유형이 의미하는 바는 다음과 같다.
     
            0x2803      하나의 characteristic을 선언하는 attribute이다.
            0xFFA3      가속도계 X-축 값을 담고 있는 attribute이다.
            0x2902      characteristic에 대한 설정을 담고 있는 attribute이다.
            0x2901      characteristic에 대한 설명을 담고 있는 attribute이다.
     
        characteristic을 선언하고 있는 attribute의 값이 의미하는 바를 살펴 보도록 하자.
     
            0x10        - characteristic의 값에 대하여 Notify(0x10)을 받을 수 있다.
            0x003A      - characteristic의 값은 핸들 0x003A로 접근할 수 있다.
            0xFFA3      - characteristic의 값은 가속도계의 X-축 값이다.
         
        위의 테이블에서 핸들 0x3A의 Permissions를 살펴 보면 X-축 값을 직접 읽거나 쓰는 것은 허용되지 않음을 알 수 있다. 그렇다면 가속도계 서비스가 X-축 값을 Notification 방식으로 전송을 시작하도록 설정해 주어야 한다. 이러한 작업은 Characteristic Descriptor들 중에서 attribute 유형이 0x2902인 Client Characteristic Configuration을 통해서 이루어진다. 해당 descriptor의 bit 값은 다음과 같이 정의되어 있다.
     
            0x0001      Notification
            0x0002      Indication
         
        따라서 Notification을 시작하도록 명령하는 것은 핸들 0x3B의 값을 0x0001로 바꾸어 주는 것이다. BTool의 Characteristic Write 영역에서 아래와 같이 지정하고 Write 버튼을 누른다.

            Characteristic Value Handle: 0x003B
            Value: 01:00
             
        이제 KeyFob을 움직여 보자. 그러면 BTool의 로그창에 가속도계의 X-축 값이 나타날 것이다. 단 한 차례만 Notification을 보내는 것이 아니라 값의 변화가 있을 때마다 그 값을 보내 준다.
           
부록. 참고 자료
 
    1. 문서
 
        가. Bluetooth Low Energy CC2540/41 Mini Development Kit User's Guide (http://www.ti.com/litv/pdf/swru270c)
            4. Using BTool
            Appendix
        나. Bluetooth Core Specifications 4.0 (https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=229737)
        다. Assigned Numbers for Bluetooth GATT services (http://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx)
 
    2. 소프트웨어

        가. Bluetooth low energy software stack and tools 1.3 (www.ti.com/blestack)
            - KeyFobDemo 애플리케이션과 BTool을 포함하고 있다.

2013년 5월 3일 금요일

[BLE] TI CC2540 Mini DK 사용하기 - Advertising Data 형식

1. 들어가기

    USB 동글에서 KeyFob을 찾을 때 BTool의 로그창을 보면 아래와 같은 Rx 데이터를 발견할 수 있다.

        [3] : <Rx> - 09:58:23.157
        -Type : 0x04 (Event)
        -EventCode : 0xFF (HCI_LE_ExtEvent)
        -Data Length : 0x18 (24) bytes(s)
         Event : 0x060D (GAP_DeviceInformation)
         Status : 0x00 (Success)
         EventType : 0x00 (Connectable Undirect Advertisement)
         AddrType : 0x00 (Public)
         Addr : 78:C5:E5:A0:0D:4C
         Rssi : 0xDB (219)
         DataLength : 0x0B (11)
         Data : 02:01:05:07:02:03:18:02:18:04:18
        [4] : <Rx> - 09:58:23.183
        -Type : 0x04 (Event)
        -EventCode : 0xFF (HCI_LE_ExtEvent)
        -Data Length : 0x19 (25) bytes(s)
         Event : 0x060D (GAP_DeviceInformation)
         Status : 0x00 (Success)
         EventType : 0x04 (Scan Response)
         AddrType : 0x00 (Public)
         Addr : 78:C5:E5:A0:0D:4C
         Rssi : 0xDB (219)
         DataLength : 0x0C (12)
         Data : 0B:09:4B:65:79:66:6F:62:64:65:6D:6F

    로그를 살펴 보면 여러 항목들 중에서 Data 항목에 대해서만 해석을 달지 않고 있음을 알 수 있다. KeyFob은 KeyFobDemo 애플리케이션을 실행하고 있는 중이다. 이제 Data 항목의 각 octet이 어떤 의미를 가지고 있는지 파악해 보자.

2. USB 동글에서 KeyFob 찾기

    분석하고자 하는 로그를 얻기 위하여 순서대로 아래의 과정을 수행한다.

        1) USB 동글을 PC에 연결한다. 장치 관리자에서 USB 동글의 포트 번호를 확인한다.
        2) BTool을 실행한다. 직렬포트 설정 대화 상자에서 USB 동글의 포트 번호를 지정한다. 다른 항목은 기본으로 설정된 값을 사용한다.
        3) Keyfob의 오른쪽 버튼(B3)을 눌러 Discoverable 모드로 진입한다.
        4) BTool의 Discover/Connect 탭에서 'Discovery' 섹션의 'Scan' 버튼을 누른다. 잠시 후 "Devices Found"의 값이 1로 바뀌는 것을 확인한다.

    BTool의 로그창에 EventType이 Connectable Undirect Advertisement와 Scan Response인 Rx 데이터가 나타날 것이다.

3. Rx 데이터의 Data 항목 해석

    위에서 제시한 두 Rx 데이터의 Data 항목은 Bluetooth Core Specification 4.0의 Low Energy 부문에서 정의하고 있는 다음 두 가지 형식에 해당한다.
 
        EventType이 Connectable Undirect Advertisement인 Rx 데이터:
     
            PDU 유형이 ADV_IND인 패킷의 AdvData
     
        EventType이 Scan Response인 Rx 데이터:
         
            PDU 유형이 SCAN_RSP인 패킷의 ScanRspData

    AdvData와 ScanRspData의 형식에 대한 설명은 다음 단원에서 제시하였으며 그에 대한 이해를 바탕으로 하여 Data 항목을 해석한 결과는 아래와 같다.

    3번 Rx 데이터의 Data 항목 해석: AdvData


    4번 Rx 데이터의 Data 항목 해석: ScanRspData


    AD Type의 값이 0x02인 경우는 장치가 제공하는 서비스가 더 많이 있지만 여기서는 일부 목록만 보여 준다는 것을 의미한다. 이 경우에는 장치와 연결을 맺은 후 모든 서비스 찾기 기능을 실행하면 전체 목록을 알아낼 수 있다.

4. advertising 채널의 패킷 형식 이해

    4.1 물리 계층
 
        - 2.4 GHz ISM 밴드 (2400 ~ 2483.5 MHz)
        - 2MHz 넓이로 40개의 RF 채널 구성
            Center frequencies
            f = 2402 + k*2 MHz, k = 0, …, 39

    4.2 연결 계층
 
        - 3개의 advertising 채널
            장치 찾기, 연결 시작하기, 데이터 방송에 사용함.
        - 37개의 data 채널
            연결된 장치간 통신을 위해 사용함.
 
    4.3 패킷 형식
 
        - advertising 채널, data 채널 모두 아래 패킷 형식을 따른다.
            Preamble (1) + Access Address (4) + PDU (2 ~ 39) + CRC (3)
 
    4.4 advertising 채널의 PDU 형식
 
        - PDU size: 2 ~ 39 octets
            Header (2) + Payload (0 ~ 37)
        - Header 형식
            PDU Type (4 bits) + RFU (2 bits) + TxAdd (1 bit) + RxAdd (1 bit) + Length (6 bits) + RFU (2 bits)
        - PDU Type에 따른 Payload 형식
            ADV_IND         : AdvA (6 octets) + AdvData (0 ~ 31 octets)
            ADV_DIRECT_IND  : AdvA (6 octets) + InitA (6 octets)
            ADV_NONCONN_IND : AdvA (6 octets) + AdvData (0 ~ 31 octets)
            SCAN_REQ        : ScanA (6 octets) + AdvA (6 octets)
            SCAN_RSP        : AdvA (6 octets) + ScanRspData (0 ~ 31 octets)
            ADV_SCAN_IND    : AdvA (6 octets) + AdvData (0 ~ 31 octets)
     
    4.5 AdvData와 ScanRspData의 형식
 
        AdvData와 ScanRspData는 동일한 형식을 따르며 연속적으로 이어지는 AD structure들로 이루어진다. AD structure의 형식은 아래와 같다.

            Length (1 octet) + AD Type (1 octet) + AD Data (Length - 1)
         
    4.6 AD Type과 AD Data 형식
 
        0x01 : Flags                    - b0 LE Limited Discoverable Mode
                                        - b1 LE General Discoverable Mode
                                        - b2 BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
                                        - b3 Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
                                        - b4 Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
        0x02 : 16-bit Service UUIDs     - More 16-bit UUIDs available
        0x03 : 16-bit Service UUIDs     - Complete list of 16-bit UUIDs available
        0x04 : 32-bit Service UUIDs     - More 32-bit UUIDs available
        0x05 : 32-bit Service UUIDs     - Complete list of 32-bit UUIDs available
        0x06 : 128-bit Service UUIDs    - More 128-bit UUIDs available
        0x07 : 128-bit Service UUIDs    - Complete list of 128-bit UUIDs available
        0x08 : Local Name               - Shortened local name
        0x09 : Local Name               - Complete local name
        0x0A : TX Power Level (1 byte)
        ....


부록. 참고 자료

    1. 문서

        가. Bluetooth Low Energy CC2540/41 Mini Development Kit User's Guide (http://www.ti.com/litv/pdf/swru270c)
            4. Using BTool
            Appendix
        나. CC2540/41 Bluetooth Low Energy Software Developer's Guide (http://www.ti.com/lit/pdf/swru271)
            4. Working with Projects using IAR Embedded Workbench 8.10.4
        다. CC2540 Bluetooth Low Energy Sample Applications Guide (http://www.ti.com/litv/pdf/swru297b)
            9. KeyFobDemo
        라. Bluetooth Core Specifications 4.0 (https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=229737)
        마. Assigned Numbers for Bluetooth GATT services (http://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx)

    2. 소프트웨어

        가. Bluetooth low energy software stack and tools 1.3 (www.ti.com/blestack)
            - KeyFobDemo 애플리케이션과 BTool을 포함하고 있다.
        나. IAR Embedded Workbench for 8051 (http://supp.iar.com/Download/SW/?item=EW8051-EVAL)
            - 30일 평가판 다운로드.

2013년 4월 29일 월요일

[라이브러리] 하나의 16진 문자를 정수로 변환하기


문자열을 숫자로 바꾸어 주는 C 표준 API는 있지만, 하나의 문자를 숫자로 바꾸어 주는 API는 없는 것 같다. 그래서 아래와 같이 문자를 정수로 바꾸어 주는 함수를 두 가지 방식으로 구현해 보았다.

#include <stdio.h>
#include <string.h>

int ctoi_v1(char c)
{
if (c >= '0' && c <= '9')
{
return (c - '0');
else if (c >= 'A' && c <= 'F')
{
return (c - 'A' + 0x0A);
}
else if (c >= 'a' && c <= 'f')
{
return (c - 'a' + 0x0A);
}
else
{
return -1;
}
}

int ctoi_v2(char c)
{
switch (c)
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case 'A': return 0x0a;
case 'B': return 0x0b;
case 'C': return 0x0c;
case 'D': return 0x0d;
case 'E': return 0x0e;
case 'F': return 0x0f;
case 'a': return 0x0a;
case 'b': return 0x0b;
case 'c': return 0x0c;
case 'd': return 0x0d;
case 'e': return 0x0e;
case 'f': return 0x0f;
default: return -1;
}
}

int main(int argc, char **argv)
{
int val = -1;

if (argc != 2)
{
printf("usage: ctoi <char>\n");
return -1;
}

if (strlen(argv[1]) != 1)
{
printf("error: only one-character argument is allowed\n");
return -1;
}

val = ctoi_v2(argv[1][0]);

if (val != -1)
{
printf("%s --> 0x%02x (%d)\n", argv[1], val, val);
}
else
{
printf("%s --> non numeric character\n", argv[1]);
}

return 0;
}

2013년 4월 28일 일요일

GIT과 함께 vimdiff 편리하게 사용하기


GIT으로 관리하고 있는 소프트웨어 프로젝트에서 수정한 파일들을 마지막으로 commit한  파일들과 비교하여 수정 내용을 간단히 확인하고자 할 때에는 아래 명령을 사용할 수 있다.

    $ git diff

하지만 수정한 내용이 많거나, 비교를 하면서 편집을 계속하고자 한다면 아래의 명령을 사용하는 것이 더욱 편리하다.

    $ git difftool -y -t vimdiff

위 명령을 실행하면 여러 종류의 비교 도구 중 하나인 vimdiff로 수정 내용을 보여 줄 것이다. vimdiff 창에서 수정 내용을 확인하고 편집을 하는데 편리하게 사용할 수 있는 명령들을 정리해 보았다.

1. 윈도우간 이동

    CTRL-W w : 다음 윈도우로 이동
    CTRL-W h : 왼쪽 윈도우로 이동
    CTRL-W j : 아래쪽 윈도우로 이동
    CTRL-W k : 위쪽 윈도우로 이동
    CTRL-W l : 오른쪽 윈도우로 이동

2. 윈도우 위치 옮기기

    CTRL-W H : 왼쪽으로 옮기기
    CTRL-W J : 아래쪽으로 옮기기
    CTRL-W K : 위쪽으로 옮기기
    CTRL-W L : 오른쪽으로 옮기기

  수직 분할 상태에서 윈도우를 상하로 이동시키면 수평 분할로 바뀐다. 

3. 폴더 열기 및 접기

  폴더 표시 (+, -)가 있는 행에서 아래 문자를 치면 폴더가 열리고 접힌다.

    zo : 폴더 열기
    zc : 폴더 접기

  모든 폴더를 한꺼번에 열거나 접을 수도 있다.

    zr : 모든 폴더 열기
    zm :  모든 폴더 접기

4. 수정한 곳으로 이동하기

    ]c : 다음 수정 부분으로 이동
    [c : 이전 수정 부분으로 이동

  앞에 숫자를 덧붙이면 여러 부분을 건너 뛰어서 이동할 수 있다.

5. 수정 내용 제거하기

  편집을 계속할 때 차이에 대한 하이라이트가 반영되지 않는 경우도 존재한다. 이 때는 아래 명령을 실행하여 하이라이트를 갱신할 수 있다.

    :diffupdate

  수정한 내용 중 일부를 제거하고자 한다면 아래 두 가지 명령 중 하나를 사용하면 된다.

    dp : 차이나는 부분의 원본 파일에서 원본 내용을 수정 파일에 적용 (diff put)
    do : 차이나는 부분의 수정 파일에서 원본 내용을 수정 파일에 적용 (diff obtain)

Llama 3.2로 문장 생성 및 챗팅 완성 실습

Llama 3.2로 문장 생성 및 챗팅 완성 실습 Running Meta Llama on Linux 문서의 내용을 참고하여 Llama 3.2 1B 모델로 다음 두 가지 기능을 실습합니다. 문장 완성 챗팅 ...