2011年1月19日 星期三

修改android裝置的boot image

參考此網頁
http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack,_Edit,_and_Re-Pack_Boot_Images

一開始要先有手機的root的權限,

取得分割表名稱
cat /proc/mtd
抓出boot.img
cat /device/mtdXX > /data/boot.img

使用上面網址提供的unpack-bootimg.pl來解開boot.img

修改完root file system 需要重包成myboot.img
mkbootfs ./boot.img-ramdisk | minigzip > my-ramdisk.cpio.gz
mkbootimg --kernel ./boot.img-kernel.gz --ramdisk my-ramdisk.cpio.gz --pagesize 2048 --cmdline 'mem=203M console=ttyMSM2 androidboot.hardware=qctmsm7x27surf' --base 0x12c00000 --output myboot.img

將device開到fastboot mode, 使用fastboot燒錄myboot.img
fastboot erase bot
fastboot flash boot myboot.img
fastboot reboot

=================================================================
若系統抓得到USB裝置,但fastboot無法抓到,可能是fastboot內沒有內建此裝置的vid, 隨便找一個android的source,到system/core/fastboot/fastboot.c加入自己的vid(可用lsusb查看vid/pid)再重編fastboot就可以了
source ../../../build/envsetup.sh;
mm;

--base的參數可由原本取出的boot.img得知
in bsp/system/core/mkbootimg/mkbootimg.c
kernel的offset為0x10008000
包成的myboot.img 最前面為一個struct boot_img_hdr
in bsp/system/core/mkbootimg/bootimg.h
boot_img_hdr 的kernel_addr在12-16 byte
使用16進位編輯器去讀取boot.img的2-16 byte(little endian)減掉kernel的offset(0x10008000)即可算出--base所需的參數

--cmdline內容也可經由16進位編輯器去讀取boot.img看到(boot_img_hdr.cmdline)

要注意的是使用unpack-bootimg.pl切出來的kernel大小可能是錯的(後面有一些多餘資料?)
實際大小須參考boot.img中的boot_img_hdr.kernel_size
然後修改mkbootimg.c, 在讀取完kernel後將boot_img_hdr.kernel_size設成正確大小
之後重編並使用此版本的mkbootimg才可正常開機

2011年1月14日 星期五

android 模擬SD card裝上

mkdir /data/virtual_sdcard

mount -o remount,rw /
rm /sdcard
ln -s /data/virtual_sdcard /sdcard
setprop EXTERNAL_STORAGE_MOUNT /sdcard

因為沒有sdcard
這樣做homerun battle第一次啟動就可以下載資料檔了

android 定時執行script

可以使用phonePrioritizer:
http://forum.xda-developers.com/showthread.php?t=558822&highlight=phoneprioritizer


可以自己寫scritp放在/sdcard/phonePrioritizer/script.txt內
然後使用UI設定執行時間間隔

也可以設定定時關機與開機時要做什麼

linux date指令顯示格式

使用date --help來查看用法

command:
date +'%Y/%m/%d'

result:
2011/01/14

2011年1月13日 星期四

linux dfs 參數

路徑為/sys/devices/system/cpu/cpu0/cpufreq/

有下列檔案:
./cpuinfo_min_freq(CPU最小頻率)
./cpuinfo_max_freq(CPU最大頻率)
./scaling_min_freq(DFS最小頻率)
./scaling_max_freq(DFS最大頻率)
./affected_cpus
./related_cpus
./scaling_governor(設定DFS方法)
./scaling_driver
./scaling_available_governors(顯示DFS方法)
./scaling_setspeed(設定CPU頻率)
./scaling_cur_freq(顯示目前CPU頻率)
./stats
./stats/total_trans
./stats/time_in_state
./stats/trans_table
./ondemand(若scaling_governor設為ondemand則會用到此資料夾的參數)
./ondemand/sampling_rate_max(最大取樣頻率)
./ondemand/sampling_rate_min(最小取樣頻率)
./ondemand/sampling_rate(設定取樣頻率)
./ondemand/up_threshold(CPU使用率大於此值則升頻)
./ondemand/down_differential(CPU使用率小於此值則降頻)
./ondemand/ignore_nice_load
./ondemand/powersave_bias(下面詳細解釋)


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

in /sys/devices/system/cpu/cpu0/cpufreq/ondemand/powersave_bias

說明
http://osdir.com/ml/kernel.cpufreq/2006-07/msg00137.html


這個值的範圍為0-1000,代表0.1%-100%

假設現在系統要切到2GHz

若powersave_bias設為100(10%),
則這次會先跳到1.8G(比預期目標少10%)

2011年1月6日 星期四

解決adb連線問題

有時候明明device插上去,driver也有抓到,不過使用adb shell就是連不進去
此時使用adb devices時發現到裝置名稱為???????????

解決的方法為:
sudo adb kill-server
sudo adb devices

如果device的名稱正確顯示就可以使用adb shell連進去

2011年1月4日 星期二

使用adb對android device輸入鍵盤事件

android 可以藉由adb shell input keyevent XXX來輸入鍵盤事件,
不過很多網路上查到的資料event只有到八十多號

可以從android developer取得最新的對應:

也可以直接參考source code:

檔案放在
KeyEvent.java (\frameworks\base\core\java\android\view)


/** Key code constant: Unknown key code. */
public static final int KEYCODE_UNKNOWN = 0;
/** Key code constant: Soft Left key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom left
* of the display. */
public static final int KEYCODE_SOFT_LEFT = 1;
/** Key code constant: Soft Right key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom right
* of the display. */
public static final int KEYCODE_SOFT_RIGHT = 2;
/** Key code constant: Home key.
* This key is handled by the framework and is never delivered to applications. */
public static final int KEYCODE_HOME = 3;
/** Key code constant: Back key. */
public static final int KEYCODE_BACK = 4;
/** Key code constant: Call key. */
public static final int KEYCODE_CALL = 5;
/** Key code constant: End Call key. */
public static final int KEYCODE_ENDCALL = 6;
/** Key code constant: '0' key. */
public static final int KEYCODE_0 = 7;
/** Key code constant: '1' key. */
public static final int KEYCODE_1 = 8;
/** Key code constant: '2' key. */
public static final int KEYCODE_2 = 9;
/** Key code constant: '3' key. */
public static final int KEYCODE_3 = 10;
/** Key code constant: '4' key. */
public static final int KEYCODE_4 = 11;
/** Key code constant: '5' key. */
public static final int KEYCODE_5 = 12;
/** Key code constant: '6' key. */
public static final int KEYCODE_6 = 13;
/** Key code constant: '7' key. */
public static final int KEYCODE_7 = 14;
/** Key code constant: '8' key. */
public static final int KEYCODE_8 = 15;
/** Key code constant: '9' key. */
public static final int KEYCODE_9 = 16;
/** Key code constant: '*' key. */
public static final int KEYCODE_STAR = 17;
/** Key code constant: '#' key. */
public static final int KEYCODE_POUND = 18;
/** Key code constant: Directional Pad Up key.
* May also be synthesized from trackball motions. */
public static final int KEYCODE_DPAD_UP = 19;
/** Key code constant: Directional Pad Down key.
* May also be synthesized from trackball motions. */
public static final int KEYCODE_DPAD_DOWN = 20;
/** Key code constant: Directional Pad Left key.
* May also be synthesized from trackball motions. */
public static final int KEYCODE_DPAD_LEFT = 21;
/** Key code constant: Directional Pad Right key.
* May also be synthesized from trackball motions. */
public static final int KEYCODE_DPAD_RIGHT = 22;
/** Key code constant: Directional Pad Center key.
* May also be synthesized from trackball motions. */
public static final int KEYCODE_DPAD_CENTER = 23;
/** Key code constant: Volume Up key. */
public static final int KEYCODE_VOLUME_UP = 24;
/** Key code constant: Volume Down key. */
public static final int KEYCODE_VOLUME_DOWN = 25;
/** Key code constant: Power key. */
public static final int KEYCODE_POWER = 26;
/** Key code constant: Camera key.
* Used to launch a camera application or take pictures. */
public static final int KEYCODE_CAMERA = 27;
/** Key code constant: Clear key. */
public static final int KEYCODE_CLEAR = 28;
/** Key code constant: 'A' key. */
public static final int KEYCODE_A = 29;
/** Key code constant: 'B' key. */
public static final int KEYCODE_B = 30;
/** Key code constant: 'C' key. */
public static final int KEYCODE_C = 31;
/** Key code constant: 'D' key. */
public static final int KEYCODE_D = 32;
/** Key code constant: 'E' key. */
public static final int KEYCODE_E = 33;
/** Key code constant: 'F' key. */
public static final int KEYCODE_F = 34;
/** Key code constant: 'G' key. */
public static final int KEYCODE_G = 35;
/** Key code constant: 'H' key. */
public static final int KEYCODE_H = 36;
/** Key code constant: 'I' key. */
public static final int KEYCODE_I = 37;
/** Key code constant: 'J' key. */
public static final int KEYCODE_J = 38;
/** Key code constant: 'K' key. */
public static final int KEYCODE_K = 39;
/** Key code constant: 'L' key. */
public static final int KEYCODE_L = 40;
/** Key code constant: 'M' key. */
public static final int KEYCODE_M = 41;
/** Key code constant: 'N' key. */
public static final int KEYCODE_N = 42;
/** Key code constant: 'O' key. */
public static final int KEYCODE_O = 43;
/** Key code constant: 'P' key. */
public static final int KEYCODE_P = 44;
/** Key code constant: 'Q' key. */
public static final int KEYCODE_Q = 45;
/** Key code constant: 'R' key. */
public static final int KEYCODE_R = 46;
/** Key code constant: 'S' key. */
public static final int KEYCODE_S = 47;
/** Key code constant: 'T' key. */
public static final int KEYCODE_T = 48;
/** Key code constant: 'U' key. */
public static final int KEYCODE_U = 49;
/** Key code constant: 'V' key. */
public static final int KEYCODE_V = 50;
/** Key code constant: 'W' key. */
public static final int KEYCODE_W = 51;
/** Key code constant: 'X' key. */
public static final int KEYCODE_X = 52;
/** Key code constant: 'Y' key. */
public static final int KEYCODE_Y = 53;
/** Key code constant: 'Z' key. */
public static final int KEYCODE_Z = 54;
/** Key code constant: ',' key. */
public static final int KEYCODE_COMMA = 55;
/** Key code constant: '.' key. */
public static final int KEYCODE_PERIOD = 56;
/** Key code constant: Left Alt modifier key. */
public static final int KEYCODE_ALT_LEFT = 57;
/** Key code constant: Right Alt modifier key. */
public static final int KEYCODE_ALT_RIGHT = 58;
/** Key code constant: Left Shift modifier key. */
public static final int KEYCODE_SHIFT_LEFT = 59;
/** Key code constant: Right Shift modifier key. */
public static final int KEYCODE_SHIFT_RIGHT = 60;
/** Key code constant: Tab key. */
public static final int KEYCODE_TAB = 61;
/** Key code constant: Space key. */
public static final int KEYCODE_SPACE = 62;
/** Key code constant: Symbol modifier key.
* Used to enter alternate symbols. */
public static final int KEYCODE_SYM = 63;
/** Key code constant: Explorer special function key.
* Used to launch a browser application. */
public static final int KEYCODE_EXPLORER = 64;
/** Key code constant: Envelope special function key.
* Used to launch a mail application. */
public static final int KEYCODE_ENVELOPE = 65;
/** Key code constant: Enter key. */
public static final int KEYCODE_ENTER = 66;
/** Key code constant: Backspace key.
* Deletes characters before the insertion point. */
public static final int KEYCODE_DEL = 67;
/** Key code constant: '`' (backtick) key. */
public static final int KEYCODE_GRAVE = 68;
/** Key code constant: '-'. */
public static final int KEYCODE_MINUS = 69;
/** Key code constant: '=' key. */
public static final int KEYCODE_EQUALS = 70;
/** Key code constant: '[' key. */
public static final int KEYCODE_LEFT_BRACKET = 71;
/** Key code constant: ']' key. */
public static final int KEYCODE_RIGHT_BRACKET = 72;
/** Key code constant: '\' key. */
public static final int KEYCODE_BACKSLASH = 73;
/** Key code constant: ';' key. */
public static final int KEYCODE_SEMICOLON = 74;
/** Key code constant: ''' (apostrophe) key. */
public static final int KEYCODE_APOSTROPHE = 75;
/** Key code constant: '/' key. */
public static final int KEYCODE_SLASH = 76;
/** Key code constant: '@' key. */
public static final int KEYCODE_AT = 77;
/** Key code constant: Number modifier key.
* Used to enter numeric symbols.
* This key is not Num Lock; it is more like {@link #KEYCODE_ALT_LEFT} and is
* interpreted as an ALT key by {@link android.text.method.MetaKeyKeyListener}. */
public static final int KEYCODE_NUM = 78;
/** Key code constant: Headset Hook key.
* Used to hang up calls and stop media. */
public static final int KEYCODE_HEADSETHOOK = 79;
/** Key code constant: Camera Focus key.
* Used to focus the camera. */
public static final int KEYCODE_FOCUS = 80; // *Camera* focus
/** Key code constant: '+' key. */
public static final int KEYCODE_PLUS = 81;
/** Key code constant: Menu key. */
public static final int KEYCODE_MENU = 82;
/** Key code constant: Notification key. */
public static final int KEYCODE_NOTIFICATION = 83;
/** Key code constant: Search key. */
public static final int KEYCODE_SEARCH = 84;
/** Key code constant: Play/Pause media key. */
public static final int KEYCODE_MEDIA_PLAY_PAUSE= 85;
/** Key code constant: Stop media key. */
public static final int KEYCODE_MEDIA_STOP = 86;
/** Key code constant: Play Next media key. */
public static final int KEYCODE_MEDIA_NEXT = 87;
/** Key code constant: Play Previous media key. */
public static final int KEYCODE_MEDIA_PREVIOUS = 88;
/** Key code constant: Rewind media key. */
public static final int KEYCODE_MEDIA_REWIND = 89;
/** Key code constant: Fast Forward media key. */
public static final int KEYCODE_MEDIA_FAST_FORWARD = 90;
/** Key code constant: Mute key. */
public static final int KEYCODE_MUTE = 91;
/** Key code constant: Page Up key. */
public static final int KEYCODE_PAGE_UP = 92;
/** Key code constant: Page Down key. */
public static final int KEYCODE_PAGE_DOWN = 93;
/** Key code constant: Picture Symbols modifier key.
* Used to switch symbol sets (Emoji, Kao-moji). */
public static final int KEYCODE_PICTSYMBOLS = 94; // switch symbol-sets (Emoji,Kao-moji)
/** Key code constant: Switch Charset modifier key.
* Used to switch character sets (Kanji, Katakana). */
public static final int KEYCODE_SWITCH_CHARSET = 95; // switch char-sets (Kanji,Katakana)
/** Key code constant: A Button key.
* On a game controller, the A button should be either the button labeled A
* or the first button on the upper row of controller buttons. */
public static final int KEYCODE_BUTTON_A = 96;
/** Key code constant: B Button key.
* On a game controller, the B button should be either the button labeled B
* or the second button on the upper row of controller buttons. */
public static final int KEYCODE_BUTTON_B = 97;
/** Key code constant: C Button key.
* On a game controller, the C button should be either the button labeled C
* or the third button on the upper row of controller buttons. */
public static final int KEYCODE_BUTTON_C = 98;
/** Key code constant: X Button key.
* On a game controller, the X button should be either the button labeled X
* or the first button on the lower row of controller buttons. */
public static final int KEYCODE_BUTTON_X = 99;
/** Key code constant: Y Button key.
* On a game controller, the Y button should be either the button labeled Y
* or the second button on the lower row of controller buttons. */
public static final int KEYCODE_BUTTON_Y = 100;
/** Key code constant: Z Button key.
* On a game controller, the Z button should be either the button labeled Z
* or the third button on the lower row of controller buttons. */
public static final int KEYCODE_BUTTON_Z = 101;
/** Key code constant: L1 Button key.
* On a game controller, the L1 button should be either the button labeled L1 (or L)
* or the top left trigger button. */
public static final int KEYCODE_BUTTON_L1 = 102;
/** Key code constant: R1 Button key.
* On a game controller, the R1 button should be either the button labeled R1 (or R)
* or the top right trigger button. */
public static final int KEYCODE_BUTTON_R1 = 103;
/** Key code constant: L2 Button key.
* On a game controller, the L2 button should be either the button labeled L2
* or the bottom left trigger button. */
public static final int KEYCODE_BUTTON_L2 = 104;
/** Key code constant: R2 Button key.
* On a game controller, the R2 button should be either the button labeled R2
* or the bottom right trigger button. */
public static final int KEYCODE_BUTTON_R2 = 105;
/** Key code constant: Left Thumb Button key.
* On a game controller, the left thumb button indicates that the left (or only)
* joystick is pressed. */
public static final int KEYCODE_BUTTON_THUMBL = 106;
/** Key code constant: Right Thumb Button key.
* On a game controller, the right thumb button indicates that the right
* joystick is pressed. */
public static final int KEYCODE_BUTTON_THUMBR = 107;
/** Key code constant: Start Button key.
* On a game controller, the button labeled Start. */
public static final int KEYCODE_BUTTON_START = 108;
/** Key code constant: Select Button key.
* On a game controller, the button labeled Select. */
public static final int KEYCODE_BUTTON_SELECT = 109;
/** Key code constant: Mode Button key.
* On a game controller, the button labeled Mode. */
public static final int KEYCODE_BUTTON_MODE = 110;






範例:


/* send android keyboard event via usb
* 2010/1/5 by chihying
*
* release not:
* v1.0 2010/1/5
* first version, no '<' and '>'
*
*
* */


#include
#include
#include
#include

#define MAX_LENGTH 10

int S;

typedef struct _cmd{
int event[MAX_LENGTH];
int event_len;
int input_len;
int input[MAX_LENGTH];
int choice;
}CMD;

CMD cmd[]={

// {{0} ,1 , ,{}},
// {{1} ,1 , ,{}},
// {{2} ,1 , ,{}},
{{3} ,1 ,5 ,{27,91,49,53,126}},//KEYCODE_HOME
{{4} ,1 ,5 ,{27,91,49,56,126}},//KEYCODE_BACK
// {{5} ,1 , ,{}},//KEYCODE_CALL
// {{6} ,1 , ,{}},//KEYCODE_ENDCALL

{{7} ,1 ,1 ,{'0'}},
{{8} ,1 ,1 ,{'1'}},
{{9} ,1 ,1 ,{'2'}},
{{10} ,1 ,1 ,{'3'}},
{{11} ,1 ,1 ,{'4'}},
{{12} ,1 ,1 ,{'5'}},
{{13} ,1 ,1 ,{'6'}},
{{14} ,1 ,1 ,{'7'}},
{{15} ,1 ,1 ,{'8'}},
{{16} ,1 ,1 ,{'9'}},
{{59,7} ,2 ,1 ,{')'}},
{{59,8} ,2 ,1 ,{'!'}},
{{59,11},2 ,1 ,{'$'}},
{{59,12},2 ,1 ,{'%'}},
{{59,13},2 ,1 ,{'^'}},
{{59,14},2 ,1 ,{'&'}},
{{59,16},2 ,1 ,{'('}},

{{17} ,1 ,1 ,{'*'}},
{{18} ,1 ,1 ,{'#'}},
{{19} ,1 ,3 ,{27,91,65}},//KEYCODE_DPAD_UP
{{20} ,1 ,3 ,{27,91,66}},//KEYCODE_DPAD_DOWN
{{21} ,1 ,3 ,{27,91,68}},//KEYCODE_DPAD_LEFT
{{22} ,1 ,3 ,{27,91,67}},//KEYCODE_DPAD_RIGHT
// {{23} ,1 , ,{}},//KEYCODE_DPAD_CENTER
{{24} ,1 ,4 ,{27,91,53,126}},//KEYCODE_VOLUME_UP
{{25} ,1 ,4 ,{27,91,54,126}},//KEYCODE_VOLUME_DOWN
// {{26} ,1 , ,{}},//KEYCODE_POWER
// {{27} ,1 , ,{}},//KEYCODE_CAMERA
// {{28} ,1 , ,{}},//KEYCODE_CLEAR

{{29} ,1 ,1 ,{'a'}},
{{30} ,1 ,1 ,{'b'}},
{{31} ,1 ,1 ,{'c'}},
{{32} ,1 ,1 ,{'d'}},
{{33} ,1 ,1 ,{'e'}},
{{34} ,1 ,1 ,{'f'}},
{{35} ,1 ,1 ,{'g'}},
{{36} ,1 ,1 ,{'h'}},
{{37} ,1 ,1 ,{'i'}},
{{38} ,1 ,1 ,{'j'}},
{{39} ,1 ,1 ,{'k'}},
{{40} ,1 ,1 ,{'l'}},
{{41} ,1 ,1 ,{'m'}},
{{42} ,1 ,1 ,{'n'}},
{{43} ,1 ,1 ,{'o'}},
{{44} ,1 ,1 ,{'p'}},
{{45} ,1 ,1 ,{'q'}},
{{46} ,1 ,1 ,{'r'}},
{{47} ,1 ,1 ,{'s'}},
{{48} ,1 ,1 ,{'t'}},
{{49} ,1 ,1 ,{'u'}},
{{50} ,1 ,1 ,{'v'}},
{{51} ,1 ,1 ,{'w'}},
{{52} ,1 ,1 ,{'x'}},
{{53} ,1 ,1 ,{'y'}},
{{54} ,1 ,1 ,{'z'}},

{{59,29},2 ,1 ,{'A'}},
{{59,30},2 ,1 ,{'B'}},
{{59,31},2 ,1 ,{'C'}},
{{59,32},2 ,1 ,{'D'}},
{{59,33},2 ,1 ,{'E'}},
{{59,34},2 ,1 ,{'F'}},
{{59,35},2 ,1 ,{'G'}},
{{59,36},2 ,1 ,{'H'}},
{{59,37},2 ,1 ,{'I'}},
{{59,38},2 ,1 ,{'J'}},
{{59,39},2 ,1 ,{'K'}},
{{59,40},2 ,1 ,{'L'}},
{{59,41},2 ,1 ,{'M'}},
{{59,42},2 ,1 ,{'N'}},
{{59,43},2 ,1 ,{'O'}},
{{59,44},2 ,1 ,{'P'}},
{{59,45},2 ,1 ,{'Q'}},
{{59,46},2 ,1 ,{'R'}},
{{59,47},2 ,1 ,{'S'}},
{{59,48},2 ,1 ,{'T'}},
{{59,49},2 ,1 ,{'U'}},
{{59,50},2 ,1 ,{'V'}},
{{59,51},2 ,1 ,{'W'}},
{{59,52},2 ,1 ,{'X'}},
{{59,53},2 ,1 ,{'Y'}},
{{59,54},2 ,1 ,{'Z'}},

{{55} ,1 ,1 ,{','}},
{{56} ,1 ,1 ,{'.'}},
// {{59,55},2 ,1 ,{'<'}},
// {{59,56},2 ,1 ,{'>'}},

// {{57} ,1 , ,{}},//KEYCODE_ALT_LEFT
// {{58} ,1 , ,{}},//KEYCODE_ALT_RIGHT
// {{59} ,1 , ,{}},//KEYCODE_SHIFT_LEFT
// {{60} ,1 , ,{}},//KEYCODE_SHIFT_RIGHT

{{61} ,1 ,1 ,{9}},//KEYCODE_TAB
{{62} ,1 ,1 ,{32}},//KEYCODE_SPACE
// {{63} ,1 , ,{}},//KEYCODE_SYM
// {{64} ,1 , ,{}},//KEYCODE_EXPLORER
// {{65} ,1 , ,{}},//KEYCODE_ENVELOPE
{{66} ,1 ,1 ,{10}},//KEYCODE_ENTER
{{67} ,1 ,1 ,{127}},//KEYCODE_DEL

{{68} ,1 ,1 ,{'`'}},
{{69} ,1 ,1 ,{'-'}},
{{70} ,1 ,1 ,{'='}},
{{71} ,1 ,1 ,{'['}},
{{72} ,1 ,1 ,{']'}},
{{73} ,1 ,1 ,{92}},
{{74} ,1 ,1 ,{';'}},
{{75} ,1 ,1 ,{39}},
{{76} ,1 ,1 ,{'/'}},
{{77} ,1 ,1 ,{'@'}},
{{59,68},2 ,1 ,{'~'}},
{{59,69},2 ,1 ,{'_'}},
{{59,71},2 ,1 ,{'{'}},
{{59,72},2 ,1 ,{'}'}},
{{59,73},2 ,1 ,{'|'}},
{{59,74},2 ,1 ,{':'}},
{{59,75},2 ,1 ,{'"'}},
{{59,76},2 ,1 ,{'?'}},

// {{78} ,1 , ,{}},//KEYCODE_NUM
// {{79} ,1 , ,{}},//KEYCODE_HEADSETHOOK
// {{80} ,1 , ,{}},//KEYCODE_FOCUS

{{81} ,1 ,1 ,{'+'}},

{{82} ,1 ,5 ,{27,91,49,55,126}},//KEYCODE_MENU
// {{83} ,1 , ,{}},//KEYCODE_NOTIFICATION
{{84} ,1 ,5 ,{27,91,49,57,126}},//KEYCODE_SEARCH
// {{85} ,1 , ,{}},//TAG_LAST_KEYCODE


};

void set_tty(){
struct termios old = {0};

if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");

old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;

if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
}

char getch(void) {
char buf = 0;

if (read(0, &buf, 1) < 0)
perror ("read()");

return (buf);
}

void send_cmd(int n){
char command[100];
for(int i=0; i sprintf(command, "adb shell input keyevent %d", cmd[n].event[i]);
system(command);
}
}

void unknow(char key){
printf("error: unknow key %d\n", key);
S=1;
}

void print_cmd(int n){
for(int i=0;i printf("%d ", cmd[n].event[i]);
}
printf("\n");
}

int main() {
char key;
int cmd_num=0, cmd_max_length=0, flag;

cmd_num=sizeof(cmd)/sizeof(CMD);
for(int i=0; i if(cmd[1].input_len>cmd_max_length)
cmd_max_length=cmd[1].input_len;
}
// printf("cmd_num=%d, cmd_max_length=%d\n", cmd_num, cmd_max_length);

set_tty();

S=0;
while((key=getch()) /*&& (key != 27)*//*ESC*/){
// printf ("you pressed %d, state=%d\n", key, S);

//unknow state
if( S<0 || S>=cmd_max_length ){
printf("error: unknow state\n");
S=0;
continue;
}

//reset choice
if(S==0){
for(int i=0; i cmd[i].choice=1;
}
}

flag=0;
for(int i=0; i if(cmd[i].choice && cmd[i].input_len>S && cmd[i].input[S]==key){
// printf("choice event: ");print_cmd(i);

flag=1;
if(cmd[i].input_len==S+1){
// printf("found keyevent: ");print_cmd(i);

flag=2;
send_cmd(i);
break;
}
}else{
cmd[i].choice=0;
}
}


if(flag==0){
printf("error: no match event\n");

S=0;
continue;
}

if(flag==1){
S++;
continue;
}

if(flag==2){
S=0;
continue;
}
}

return(0);
}