페이지

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일 평가판 다운로드.

국어 맞춤법 참고 자료

  제목 설명(인용) 출처 IT 글쓰기와 번역 노트 IT 기술 문서 및 서적을 집필/번역/교정하면서 얻은 경험/정보/지식을 공유합니다. 전뇌해커 [우리말 바루기] ‘대로’의 띄어쓰기 명사 뒤에서는 붙여 쓰고, 그 외에는 띄어 쓴다고 생각하면 쉽다. 다...