조잡 어플리케이션 시리즈 2 : Android SMS Tethering Swich Application

3년 전에 만들었던 SMS Forward에 이어 최근에 만든 조잡 어플리케이션 2호 Android SMS Tethering Swich Application 이다.

지난 3년간 SMS Forward Application으로 업무폰의 데이터를 개인폰으로 선물하면서 아무런 불편없이 모바일 라이프를 잘 하던 중 어느날 한계점이 찾아왔다. 데이터 선물하기로 개인폰에 보낼 수 있는 데이터는 2기가가 한계인데(SKT 이거 좀 늘려랏!) 어느순간 지하철에서 페북과 유투브 동영상을 자주 보게 되면서 2기가로는 택도 없는 상태가 되었기 때문이다. 그래서 생각난 것이 업무폰을 테더링 머신으로 들고다니면 어떨까? 하는 것이었다.

처음은 뭐 괜찮은듯 했지만 곧바로 새로운 장애물에 부딪혔는데 3년이나 된 업무폰이 배터리가 거의 다 맛이 가서 골골댄다는 것이다. 테더링 2시간이면 폰이 꺼졌다. 업무용 폰을 새로 지급 받을까 했지만 제대로 쓰지도 않을 비싼 폰을 새로 받기는 좀 찜찜하기도 해서 이러지도 저러지도 못하고 있다가 마침 안드로이드 개발자인 나에게 테스트용 새 폰이 지급되었다. 그래서 다음과 같은 뻘짓을 해봤는데

1. 업무폰으로 데이터 쉐어링 서비스 신청해서 데이터 전용 USIM을 발급 받는다. 이 데이터 전용 USIM은 전화 발신, SMS 발신 기능이 제한된다.
2. 개발자 테스트용 폰에 데이터 전용 USIM을 장착한다.
3. 이제 배터리가 빵빵한 개발자 테스트용 폰을 테더링 머신으로 들고다닌다.

제법 괜찮았다. 다만 한가지 불편함이 있는데 아무리 배터리 빵빵한 신형폰도 테더링을 켜놓음녀 10시간도 버티기 어렵다는 것이다. 그래서 테더링 폰을 가방에 넣고 다니면서 필요할때만 테더링을 껏다 켰다 했어야 했는데 이거 은근 불편하고 잠깐만 아차하면 배터리 광탈 당하는 상황을 면치 못했다.

그러다 한가지 재미있는 사실을 알게 되었는데 데이터 전용 USIM도 SMS 수신은 된다는 것이다. 그래서 생각해본게 SMS Foward 비슷하게 SMS로 테더링을 on/off 시키는 앱을 만들어 보는 것이었다. 테더링 on/off 메소드가 public으로 제공되지 않아 난감했지만 우리에게 역시 구글신이 계시다. 여기저기 구글링하니 곧바로 방법이 나오더라. 결국 Java reflection으로 WifiService 객체에 숨겨진 테더링 제어 메소드를 찾아 돌리는 방법밖에 없더라.

여튼 만들고 나니 잘 동작했다. 만든 시점부터 현재까지 SMS로 개발폰의 테더링을 on/off 하고 있는데 확실히 이전보다 불편함이 줄었다. 무엇보다 SKT가 데이터 요금 강화하려는 의도인지 전화/SMS가 무료인 요금제를 내놓아서 문제비용 걱정도 없어졌다.

sms_tethering_application

UI는 SMS Forward보단 좀 복잡해졌다. 일단 SMS로 테더링을 켜는 문자열과 SMS로 테더링을 끄는 문자열을 입력하면 그걸 기준으로 SMS를 필터링 해서 테더링을 on/off한다. 그리고 테더링 제어 결과를 SMS로 알려주는 기능도 넣긴 했는데 안타깝게도 개발에 사용한 데이터 쉐어 USIM이 문자 발송 제한이 걸려있어 제대로 작동하는지 테스트 해보진 못했다.

하루 정도 테스트후 개발폰의 SMS를 열어보면 무슨 정신 분열자가 같은 느낌이 난다. 좌측이 테더링 머신, 우측이 개인폰이다. 테더링 머신의 테더링 결과 문자발송 실패 아이콘을 보면 뭔가 가슴아프다.

sms_tethering_machinesms_my_phone

 

 

 

 

 

 

 

 

 

 

현재까지 불편없이 잘 쓰고 있다. 다만 SMS로 ‘꺼’ 날리는 거 조차 잊어서 종종 방전된 개발폰을 보아야 하는 문제점이 있는데 이건 해결이 불가능 하다. 테더링 켜지고 2시간 뒤 자동으로 꺼지는 기능이라도 추가해야 하나?

github link : https://github.com/abh0518/sms_tethering_switch

조잡 어플리케이션 시리즈 1 : Android SMS Forward Application

3년전 SK Planet에 입사하며 고민중 하나가 회사에서 데이터가 빵빵하게 제공되는 업무폰을 지원해준다는 것이었다. 보통들은 개인폰을 해지하고 업무폰으로 갈아탔지만 난 왠지 모르게 개인폰을 해지하기 싫어서 폰을 두개씩 달고 다니기 시작했다. 아이폰은 계속 쓰고 싶지만 그렇게 하기엔 업무폰을 안드로이드로 선택할 경우 지원되는 티스토어와 호핀 혜택이 너무 빵빵했다는 것도 이유중 하나다.

그래서 개인용 아이폰을 최저요금으로 유지하고 업무폰을 데이터 선물하기와 티스토어, 호핀 전용 머신으로 사용하게 되었다. 그렇게 사용하던 중 불편한 점을 하나 발견했는데 업무폰으로 연계되는 서비스를 사용할 때 마다 방 구석 깊숙히 충전잭에 박혀있는 폰을 꺼내서 SMS인증을 해줘야 한다는 것이다.

그래서 귀차니즘에 안드로이드용 SMS 전달 앱을 만들어 써봤다니 제법 편리해졌다. 데이터 선물하기든 호핀이든 웹이나 아이폰 앱에서 결제한 후 내 개인폰으로 전달된 SMS로 인증하면 끝이이니 이런 신세계가!

sms_forward_application

UI는 그낭 SMS를 전달할 번호 입력하고 save하면 끝이고 SMS는 필터링이고 나발이고 오는건 죄다 전달 해버리는 뭔가 조악한 놈이지만 아직까지 잘 쓰고 있다.

github link : https://github.com/abh0518/sms_forward

최고의 루비 버전 관리 툴 rbenv

최근에 발견한 루비 버전 관리툴 rbenv

rvm보다 설치하기 쉽고 사용하기도 쉽고 편리하다.

rvm과 달리 시스템 설정쪽을 전혀 건드리지 않는다는 점은 정말 최고다!

플러그인 ruby build 까지 함께 설치해서 사용하면 더욱 최고!

https://github.com/sstephenson/rbenv

https://github.com/sstephenson/ruby-build

루비 개발자라면 강추! 강추! 강추!

안드로이드용 SMS 재전송 어플리케이션

요즘 찾아온 멘붕을 극복하기 위해 재미삼아 만들어본 Android용 SMS Forwarding Application이다.
( + 핸드폰 결제 할 때마다 SMS인증을 위해 임직원폰을 계속 찾아 헤메야 하는 불편함을 없애고 싶었기도 하고…)

그냥 새로 도착한 SMS가 있으면 지정된 폰번호로 다시 재전송해주는 간단한 어플이다.

2년만에 안드로이드 어플 개발을 해보면서 느낀건, 역시 안드로이드 UI작업은 스트레스 만땅이다.

Eclipse 플러그인이 2년전 보다 많이 나아지긴 했지만 여전히 불편한건 어쩔 수 없다.

그럼 오늘은 호핀 결제를 한번 해볼까…..

https://github.com/abh0518/sms_forward

Ruby, __FILE__ 과 $0의 유용성

루비로 개발을 하면서 Java와 다르게 재미난(?) 환경 변수가 있다는걸 알게되었는데, 그게 __FILE__ 과 $0 이다.

__FILE__은 현재 실행 되고 있는 ruby file path, $0는 main으로 실행된 ruby file path, 즉 첫번째로 실행된 ruby file을 알려준다. 어떻게 보면 별거 아닌 것일 수도 있는데, 여러 작업에서 유용하게 쓰인다.

1. main script 작성에 활용


# 현재 파일이 main으로 실행되었는지 확인하는 구문
if __FILE__ == $0 then
# main  code 작성
end

 Ruby가 script언어이다 보니 Java나 C같은 언어와 다르게 프로그램의 시작을 알려주는 main이란  구역이 없다.  이런 단점은 main역할을 하는 code를 담고 있는 script가 다른 module에서 로드될때 많은 골칫거리를 만들어 내게 하는데,  이부분은 __FILE__과 $0로 쉽게 해결 가능하다.
위 코드의  if문 안의 코드들은 현재의 파일이 main으로 실행되었을 때만 작동하므로  Java나 C의 main과 다를 것이 없다.

 

2. require 경로를 상대적으로 기술

home = File.join(File.dirname(__FILE__), ‘/..’)
require File.join(home, ‘lib/usage_collector’)

그냥 require(path)를 하게되면 실행 path의 영향을 받기 때문에 상황에 따라 require가 파일을 제대로 찾지 못할 경우가 많다. 대표적으로  gem으로 잘 돌아가던게 소스로 받아서 돌리면 안되거나 source로 실행할때는 잘되던게 gem으로 만들면 안돌아간다.
초기 작성시 위의 소스 코드처럼 __FILE__을 사용하여 home을 확실하게 지정해주면 require 엄한 위치를 헤메는 일이 없어진다. 이렇게 작성해 놓으면 gem으로 실행하든 source 상태로 실행하든 상관없이 잘 돌아간다.

 

3. 그외 이런저런 파일 작업을 다룰때에도…
그외에도 파일을 다루다보면 기준 경로를 어디로 잡을 것인지가 매우 골치아픈 문제이다. __FILE__과 $0 이런 문제들을 쉽게 해결할 수 있는 단서를 제공해준다.

 

Java Toy Project – State Machine (1)

음, 뭐 재미로 만들어 볼꺼 없나 고민하다가 Automata State Machine을 구현해보면 어떨까 하는 생각이 들었다.
=> 전이와 상태를 정의해주면 Input을 알아서 촥촥 처리해주는 뭐 그런 알흠다운 녀석??

가능하면 여러군데서 유틸리티로 사용할 수 있도록 범용 프로그램으로 개발하는게 좋을거 같은데, 대충 생각나는 건….

  1. 머신의 상태와 전이 규칙을 사용자가 자유롭게 정의할 수 있어야 한다.
    => yaml, xml 형태로 작성할 수 있어야 한다.
  2. 각 전이때마다 무슨짓(?)을 할지 사용자가 프로그래밍 해 넣을 수 있어야 한다. POJO형태로 쓸 수 있도록 한다.
  3. 사용자가 Input과 Output을 어떻게 정의할지 좀더 고민이 필요하다.
    => 요게 잘되면 구문분석기 같은거로도 사용할 수 있지 않을까?

State Pattern을 좀 응용하면 쉽지 않을까……? 하는데, 역시 만들어 봐야 할것지? 꿈만 큰가?

 

 

Ruby Daemon Process 만들기

==========

#!/usr/bin/env ruby

# fork로 Daemon Process 만들기
pid = fork do

Process.setsid                  # Process에 새로운 pid 할당 (fork된 Daemon이 지금의 부모 프로세스에서 떨어져 나와 최상위 프로세스의 자식 프로세스로 변경된다.)
exit if fork                         # 부모 프로세스 종료
trap(“TERM”) { exit }  # 시그날 설정(?), 이건 왜 쓰는지 잘 모르겠다…
  Dir.chdir(“/”)                # 실행 디렉토리를 / 로 변경, Damon 프로그램끼리 파일 경로 헷갈리지 않도록 하기 위한 관례

# STDIN, STDOUT, STDERROR가 출력되지 않도록 /dev/null 로 출력 방향을 바꾸어 줌
 STDIN.reopen “/dev/null”
 STDOUT.reopen “/dev/null”, “a”
 STDERR.reopen “/dev/null”, “a” 

 

# 여기서부터 Daemon으로 작동할 code 작성!
  # blablabla~~~

end

==============

 

자세한 내용은 아래 링크에서
http://www.jstorimer.com/2012/04/19/daemon-processes-in-ruby.html

pg_runner – Ruby용 Postresql Utility

Ruby로  백그라운드에서 postgresql 작업을 하는 데몬 프로그램을 만드는 중인데, Ruby on rails의 Active Record에 쓰기에는 너무 오바인거 같고 Single Connection으로 만들기에는 뭔가 아쉽고 불안하다.

여기저기 뒤져보다가 딱히 맘에드는 connection pool이 없어서 연습삼아 만들어 봤는데, 생각보다 잘돌아간다. (속도는 아직 보장 못함)  Pool로 사용할 Synchronized Array를 루비에서 지원해주는지 알길이 없어 여기저기 뒤져보다 마음을 무겁게 만드는 영문의 압박에 그냥 비슷한 기능하는 Wrapper 클래스를 만들어 썻다. 다행이 이것도 생각보다 잘돌아 간다. (Array Wrapper에 Mutex만 걸어준거니 안돌아 가는게 이상하겠지만. @_@)

현재 버전에서 아쉬운점은 transaction기능이 없고 postgresql 전용이라는거…
다음에 시간날때 추가해봐야겠다.

요번에 만드는 모듈에 이거 넣어야지 헤헤헤헤….

궁금하신 분들은 (있을까 모르겠지만 ) 다음 링크를 참조하시길…

https://github.com/abh0518/pg_runner

GEM 만들기

루비는 GEM이라는 재미난 형태의 패키지 기능을 제공한다. 자바의 jar와 비슷한 개념이기도 한데 특이한건 만드는 방법에 따라 Gem이 라이브러리로 쓰이기도 하고 실행가능한 어플리케이션이 되기도 한다. 만들기도 쉽고 사용하기도 쉽다.

애당초 루비 개발을 시작할때 디렉토리 구조를 Gem구조로 가져가는것이 속편하고 좋다.

1. gem을 위한 기본 소스 디렉토리 구성
“source root” —- bin
|– lib
|– ${gemname}.gemspec

  • bin에는 실행가능한 루비 소스 파일들을 배치한다. 실행 가능해야하니 rb파일 첫줄에 쉬뱅 라인을 넣는 것을 잊지 말자
    ( 리눅스 환경에서는 #!//usr/bin/env ruby 가 일반적이다. )
  • lib에는 라이브러리로 쓰이는 루비 소스 파일들을 배치한다. 대부분 개발 파일들이 이 디렉토리에 위치한다. (실행파일들 빼고~)
  • ${gemname}.gemspec , gem을 빌드할때 참조하는 스펙 파일. 요건 다음 항목에서 상세히…

2. gemspec 작성
gem build시 참고하는 spec파일, 만들어질 gem file들에 대한 정보를 포함하고 있다.
아래는 최근에 개발한 uasge_collector 라는 젬 파일의 usage_collector.gemspec 파일 내용
——- usage_collector.gemspec ————–
require ‘rubygems’

Gem::Specification.new do |s|
s.name = ‘cloulu_usage_collector’ # gem list 에 표기되는 gem name
s.version = ‘0.1.0’                           # gem version 표기
s.date = ‘2013-04-05’
s.summary = “CloudFoundry DEA Usage Collector” # gem list에 표기되는 gem 설명
s.description = “A Cloulu project’s Component developed to collect cpu usage of CloudFoundry’s DEA Apps”
s.authors = [“abh0518”]
s.email = ‘abh0518@gmail.com’
s.bindir = ‘bin’  # 실행 파일이 위치한 디렉토리
s.executables = [‘usage_collector’] # 실행 파일 목록, 배열 형식으로 나열
s.files = Dir.glob(“**/**/**”) # 젬에 포함되는 파일들, Dir.glob(“**/**/**”) 는 모든 파일들을 포함시켜 버린다.
s.homepage = ‘http://www.facebook.com/abh0518’
end
————————————————————–

3. gem 만들기
gem build에 2에서 작성한 spec파일 path를 파라메터로 넘겨준다.
>> gem build ${gemspecfile path”}

4. gem 설치
3이 완료되면 드더에 gem으로 만들어진 파일을 얻을 수 있다. 간단히 설치해보자
>> gem install “gem file name”

5. gem 설치 확인
>> gem list

6. 기타 gem 명령어들 (잊지 않기위해 일단 나열만 해놓음)

  • gem list # 설치된 젬 리스트 표시
  • gem environment # 루비 젬 설정 환경 표시
  • gem update ${gem name} # 지정한 젬 업데이트
  • gem update # 모든 젬 업데이트
  • gem update –system # Ruby Gem 자체를 업데이트
  • gem uninstall ${gem name} # 설치한 젬 제거