加密功能完成了 , 寫一個測試程式來試試看吧 !!
首先要說明 , 這個程式原作者是 Alvin , 我借用這個程式修改一下來測試 !!
這個程式會 Create /tmp/t01.db , 並且設定加密 key .
然後填寫一些固定的 data 到 db 中 , 並且dump , quary 等一些機本操作 !!
接著執行 rekey 功能 (移除 key ) , 如果不想移除 key 可以用 Ctrl + C 中斷 !!
然後用 cat 看看 t01.db 的內容 是否有加密 !!
執行完 rekey 後一樣有 dump , quary 功能 , 可以比對加密/ 沒加密是否有錯誤 !!
當然 rekey 後也可用 cat 看看 t01.db 的內容
增加方式如下:
A.增加一個資料夾 sql-test.並且建立 Andorid.mk file.
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/Android.mk 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/Android.mk 2013-05-27 13:46:53.090414327 +0800
@@ -0,0 +1,32 @@
+##
+##
+## Build test program
+##
+##
+
+
+ifeq ($(CONFIG_PRJ_RELASE_TEST),y)
+
+LOCAL_PATH:= $(call my-dir)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := sqlkey.c
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/../dist
+
+LOCAL_SHARED_LIBRARIES := libsqlite
+
+LOCAL_CFLAGS += -I$(LOCAL_PATH) -DSQLITE_HAS_CODEC=1
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE := sqlkey
+
+include $(BUILD_EXECUTABLE)
+
+endif
+
B.建立一個 db.h , 這是程式程式要用 heard file.
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/db.h TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/db.h
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/db.h 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/db.h 2013-05-27 11:02:01.742571654 +0800
@@ -0,0 +1,38 @@
+#ifndef __DB_H__
+#define __DB_H__
+
+#include "i_basetype.h"
+#include <sqlite3.h>
+
+#define MAX_SQL_LEN 1024 //
+#define MAX_DB_CNT 50
+
+typedef struct {
+ sqlite3 *db;
+ SCHAR *cmd;
+ SCHAR *exe;
+ UINT opt;
+ SINT ret;
+ UINT *width;
+
+ int row;
+ int col;
+ UINT total;
+ FREE SCHAR **result;
+ SCHAR *errmsg;
+ SINT (*callback)(void *data, int argc, char **argv, char **columnNames);
+ VOID *callback_arg;
+} SQL_CMD;
+
+#define SQL_OPT_SHOW 0x01 // show result & message
+#define SQL_OPT_MFREE 0x80 // manually free
+
+
+extern sqlite3 *m_db;
+
+int sql_execx(SQL_CMD *sql, char *fmt, ...);
+void sql_freex(SQL_CMD *sql);
+sqlite3 *db_open(SCHAR* db_name);
+void db_close(sqlite3 *db);
+
+#endif // __DB_H__
C.建立 i_basetype.h , 主要定義一些基本的結構和資料 Type.
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/i_basetype.h TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/i_basetype.h
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/i_basetype.h 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/i_basetype.h 2013-05-27 11:01:46.815417060 +0800
@@ -0,0 +1,113 @@
+//
+#ifndef __I_BASETYPE_H__
+#define __I_BASETYPE_H__
+
+typedef char SCHAR; // 8-bit
+typedef short SSHORT; // 16-bit
+typedef int SINT; // 32-bit
+typedef long SLONG; // 32-bit
+typedef long long SLONGLONG; // 64-bit
+/*
+typedef signed char SCHAR; // 8-bit
+typedef signed short SSHORT; // 16-bit
+typedef signed int SINT; // 32-bit
+typedef signed long SLONG; // 32-bit
+typedef signed long long SLONGLONG; // 64-bit
+*/
+
+typedef unsigned char UCHAR; // 8-bit
+typedef unsigned short USHORT; // 16-bit
+typedef unsigned int UINT; // 32-bit
+typedef unsigned long ULONG; // 32-bit
+typedef unsigned long long ULONGLONG; // 64-bit
+
+#ifndef __BASE_TYPE_DEFINED__
+#define __BASE_TYPE_DEFINED__
+
+typedef unsigned int BOOL; // 32-bit
+
+typedef unsigned char UINT8; // 8-bit
+typedef unsigned short UINT16; // 16-bit
+typedef unsigned int UINT32; // 32-bit
+typedef unsigned long long UINT64; // 64-bit
+
+typedef signed char SINT8; // 8-bit
+typedef signed short SINT16; // 16-bit
+typedef signed int SINT32; // 32-bit
+typedef signed long long SINT64; // 64-bit
+
+#endif // __BASE_TYPE_DEFINED__
+
+typedef void VOID; // 32-bit
+typedef float FLOAT; // 32-bit
+typedef double DOUBLE; // 64-bit
+
+typedef struct {
+ union {
+ SCHAR c;
+ SSHORT s;
+ SINT i;
+ SLONG l;
+ SLONGLONG ll;
+ UCHAR b;
+ USHORT w;
+ UINT u;
+ ULONG q;
+ ULONGLONG lq;
+ FLOAT f;
+ DOUBLE d;
+ VOID *p;
+ } v;
+} VALUE; // 64-bit/8 bytes
+
+#ifndef IO
+ #define IO
+#endif
+#ifndef IN
+ #define IN
+#endif
+#ifndef OUT
+ #define OUT
+#endif
+
+#ifndef FREE
+ #define FREE
+#endif
+
+#ifndef TRUE
+ #define TRUE 1
+#endif
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+
+#ifndef MIN
+ #define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+ #define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifndef ABS
+ #define ABS(x) (((x)>=0)? (x): -(x))
+#endif
+
+#ifndef DIM
+ #define DIM(var,type) (sizeof(var)/sizeof(type))
+#endif
+
+#ifndef OFFS
+ #define OFFS(type,item) ((UINT)&(((type*)0)->item))
+#endif
+
+#ifndef SIZE
+ #define SIZE(type,item) (sizeof(((type*)0)->item))
+#endif
+
+#ifndef BITMASK
+ #define BITMASK(b) ((ULONG)0x01UL << (b))
+#endif
+
+#endif // __I_BASETYPE_H__
D. 主要程式.
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/sqlkey.c TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/sqlkey.c
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/sql-test/sqlkey.c 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/sql-test/sqlkey.c 2013-05-27 10:56:06.118859064 +0800
@@ -0,0 +1,346 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "db.h"
+#include <sqlite3.h>
+
+
+#define DB_FILE "/tmp/t01.db"
+
+//========================
+sqlite3 *m_db=NULL;
+
+int sql_execx(SQL_CMD *sql, char *fmt, ...)
+{
+ static char cmd[PATH_MAX];
+ int rc=0, sel=0;
+ va_list args;
+
+ if(m_db==NULL)
+ {
+ printf("database not opened.\n");
+ return(-100);
+ }
+ sql->db=m_db;
+ sql->exe=cmd;
+ sql->ret=0;
+ sql->row=0;
+ sql->col=0;
+ sql->total=0;
+ sql->result=NULL;
+ sql->errmsg=NULL;
+ //
+ va_start(args, fmt);
+ cmd[PATH_MAX - 1] = '\0';
+ sprintf(cmd, fmt, args);
+ va_end(args);
+
+ if(strncmp(cmd, "select", 6)==0)
+ sel=1;
+ if(sel)
+ rc = sqlite3_get_table(sql->db, cmd, &sql->result, &sql->row, &sql->col, &sql->errmsg);
+ else
+ rc = sqlite3_exec(sql->db, cmd, NULL /* callback */, NULL /* callback_arg */, &sql->errmsg);
+ if(SQLITE_OK != rc)
+ {
+ if(sql->opt&SQL_OPT_SHOW)
+ printf("* SQL error! cmd='%s', err=%d (%s).\n", cmd, rc, sql->errmsg);
+ return(-rc);
+ }
+ if(sel)
+ {
+ int r, c;
+
+ rc=sql->row;
+ if(sql->opt&SQL_OPT_SHOW)
+ {
+ printf("--------------------------------------\n");
+ printf("SELECT: row=%d, col=%d, rc=%d.\n", sql->row, sql->col, rc);
+ printf("--------------------------------------\n");
+ for(r=0; r<=sql->row; r++)
+ {
+ for(c=0; c<sql->col; c++)
+ printf("%-*s", (sql->width? sql->width[c]: 16), sql->result[(r*sql->col)+c]);
+ if(sql->row)
+ printf("\n");
+ }
+ printf("--------------------------------------\n");
+ }
+ if((sql->opt&SQL_OPT_MFREE)==0)
+ {
+ sqlite3_free_table(sql->result);
+ sql->result=NULL;
+ }
+ }
+ return(sql->ret=rc);
+}
+
+void sql_freex(SQL_CMD *sql)
+{
+ if(sql->result)
+ {
+ sqlite3_free_table(sql->result);
+ sql->result=NULL;
+ }
+}
+
+sqlite3 *db_open(char* db_name)
+{
+ int rc=0;
+ sqlite3 *db=NULL;
+
+ //open a database, create it if doesn't exist.
+ if((rc=sqlite3_open(db_name, &db))!=SQLITE_OK)
+ {
+ printf("sqlite3_open() failed, db='%s', err=%d (%s).\n", db_name, rc, sqlite3_errmsg(db));
+ return(NULL);
+ }
+
+ m_db = db;
+ return(db);
+}
+
+void db_close(sqlite3 *db)
+{
+ if(db)
+ sqlite3_close(db);
+
+}
+
+void ap_initial(void)
+{
+ if((m_db=db_open(DB_FILE))==NULL)
+ printf("db_open() failed, file=%s\n", DB_FILE);
+}
+
+void ap_shutdown(void)
+{
+ if(m_db)
+ db_close(m_db);
+}
+
+int main(int argc, char* argv[])
+{
+ int rc=0;
+
+ SQL_CMD sql;
+
+ printf("=== SQLite test utility v0.1 - Alvin, 2009/03/08 ===\n");
+ ap_initial();
+
+ sqlite3_key(m_db,"1q2w3e4r",8);
+
+
+ memset(&sql, 0, sizeof(sql));
+ sql.db = m_db;
+ sql.opt = SQL_OPT_SHOW;
+
+/*
+create table dict_tbl(vocab text, sentence text, name text);
+*/
+
+ printf("Testing Create Table\n");
+ getchar();
+
+ if((rc=sql_execx(&sql, "create table dict_tbl(vocab text, sentence text, name text)"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("=== Done. ===\n");
+
+ printf("Testing Insert data\n");
+ getchar();
+
+
+
+//insert into dict_tbl values('a', 'This is an apple.', '陳奕迅先生');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('a', 'This is an apple.', '陳奕迅先生')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('book', 'This is a book.', '陳曉東先生');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('book', 'This is a book.', '陳曉東先生')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('he', 'He is a good student.', '張宇先生');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('he', 'He is a good student.', '張宇先生')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('let', "Let's go for shopping.", '張信哲先生');
+
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('let', 'Let-s go for shopping.','張信哲先生')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('sample', 'The sample is very easy.', '張學友先生');
+
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('sample', 'The sample is very easy.', '張學友先生')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('she', 'She is more beautiful than you.', '范瑋琪小姐');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('she', 'She is more beautiful than you.', '范瑋琪小姐')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('that', 'That is my desk.', '陳珊妮小姐');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('that', 'That is my desk.', '陳珊妮小姐')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+//insert into dict_tbl values('this', 'This is your sample.', '張惠妹小姐');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('this', 'This is your sample.', '張惠妹小姐')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+//insert into dict_tbl values('tomorrow', 'I will go to USA tomorrow.', '陳慧琳小姐');
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('tomorrow', 'I will go to USA tomorrow.', '陳慧琳小姐')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+//insert into dict_tbl values('you', 'You are so beautiful.', '張清芳小姐');
+
+ if((rc=sql_execx(&sql, "insert into dict_tbl values('you', 'You are so beautiful.', '張清芳小姐')"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("=== Done. ===\n");
+
+ printf("Testing dump data \n");
+ getchar();
+
+ if((rc=sql_execx(&sql, "select * from dict_tbl"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("=== Done. ===\n");
+
+ printf("Testing quary '*you*' data \n");
+ getchar();
+
+//select sentence from dict_tbl where sentence like '%you%';
+ if((rc=sql_execx(&sql, "select sentence from dict_tbl where sentence like '%%you%%'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("Testing quary '*is*you*' data \n");
+ getchar();
+
+//select sentence from dict_tbl where sentence like '%is%you%';
+ if((rc=sql_execx(&sql, "select sentence from dict_tbl where sentence like \"%%is%%you%%\""))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '*is*a*' data \n");
+ getchar();
+
+//select sentence from dict_tbl where sentence like '%is%a%';
+ if((rc=sql_execx(&sql, "select sentence from dict_tbl where sentence like '%%is%%a%%'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("=== Done. ===\n");
+ printf("Testing rekey\n");
+ getchar();
+
+ sqlite3_rekey(m_db,"",0);
+
+ printf("=== Done. ===\n");
+ printf("Testing dump data after rekey\n");
+ getchar();
+
+
+ if((rc=sql_execx(&sql, "select * from dict_tbl"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+ printf("=== Done. ===\n");
+
+ printf("Testing quary '陳*' and sentence like '*book*' data \n");
+ getchar();
+
+//select * from dict_tbl where name like '陳%' and sentence like '%book%';
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '陳%%' and sentence like '%%book%%'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '張*' data \n");
+ getchar();
+
+//select * from dict_tbl where name like '張%';
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '張%%'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '陳*先生' data \n");
+ getchar();
+
+//select * from dict_tbl where name like '陳%先生';
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '陳%%先生'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '張*小姐' data \n");
+ getchar();
+//select * from dict_tbl where name like '張%小姐';
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '張%%小姐'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '*小姐' data \n");
+ getchar();
+
+//select * from dict_tbl where name like '%小姐';
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '%%小姐'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+
+ printf("Testing quary '*先生' data \n");
+ getchar();
+
+//select * from dict_tbl where name like '%先生'; --> error
+
+ if((rc=sql_execx(&sql, "select * from dict_tbl where name like '%先生'"))<0)
+ {
+ printf("* SQL error, cmd=%s, rc=%d (%s).\n", sql.exe, rc, sql.errmsg);
+ }
+
+ printf("=== Done. ===\n");
+ getchar();
+
+ sql_freex(&sql);
+ ap_shutdown();
+
+ return 0;
+}
結果 ...... 正確沒有問題 , 打完收工 .......
2013年5月27日 星期一
Andorid Sqlite 加密功能
因為我們應用的需求,資料庫需要加密(不想被別人用adb pull 就取得資料庫)
Andorid 已經有使用sqlite 來超作資料庫,但是sqlite 沒有加密功能,所以只要自行處理 !!
不過 sqlite 有預留加密的進入點 !!
就一步一步來吧 !!
A.首先先打開 SQLITE_HAS_CODEC 這個 define.
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/Android.mk 2013-05-27 13:37:12.767651814 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/Android.mk 2013-05-24 18:55:23.884236340 +0800
@@ -27,7 +27,8 @@
-DSQLITE_OMIT_BUILTIN_TEST \
-DSQLITE_OMIT_COMPILEOPTION_DIAGS \
-DSQLITE_OMIT_LOAD_EXTENSION \
- -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600
+ -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600\
+ -DSQLITE_HAS_CODEC=1
common_src_files := sqlite3.c
B.Modify sqlite3.c file.
sqlite在編譯之前(Standard method) 會將所有 .c file 合併成為一個 .C file ( 我不知道為何要這樣 )
所以在BSP 內找到對應的檔案, 並且開始修改 !!
在 "Begin file attach.c" 之前開始插入修加密所需要的 code ;
詳細加密的功能可以參考下列網址 :
http://lancelot.blog.51cto.com/393579/940816
這網頁說的蠻清楚的 , 不過因為之前我們舊機種就已經有使用 (linux + GTK 架構 ) , 所以
就移植過來.
因為兩個版本不同,移植過來有些問題 , 所以需要修改一些小東西 , 可以參考下列網址 , 還蠻清楚的 !!
http://lancelot.blog.51cto.com/393579/940814
修改後的 diff 內容如下 , 不過太長加上有些機密問題 (加密方式 ) 所以我只列出一小部份:
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/sqlite3.c TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/sqlite3.c
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/sqlite3.c 2013-05-27 13:37:12.802652106 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/sqlite3.c 2013-05-27 13:33:06.551572993 +0800
@@ -80395,6 +80395,501 @@
#endif /* SQLITE_OMIT_ANALYZE */
/************** End of analyze.c *********************************************/
+/************** Begin file key.c ******************************************/
+
+#ifdef SQLITE_HAS_CODEC
+
+//======== main codec function.
+typedef struct _CryptBlock
+{
+ char *ReadKey;
+ char *WriteKey;
+ int PageSize;
+ char *Data;
+
+} CryptBlock, *LPCryptBlock;
+
+#ifndef DB_KEY_LENGTH_BYTE
+ #define DB_KEY_LENGTH_BYTE 16
+#endif
+
+#ifndef DB_KEY_PADDING
..........
+#endif
+
+#define CRYPT_OFFSET 8
+#define CRYPT_ROW_SIZE 32
+
+int getSBoxValue(int num)
+{
.........................
+ return sbox[num];
+}
+
+int getSBoxInvert(int num)
+{
.................
+return rsbox[num];
+}
+
+int Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )
+{
+unsigned int i,j;
+//unsigned char *temp1,*temp2,
+unsigned char *sData;
+
+//Encode functino
............................
+ free(sData);
+ return 0;
+}
+
+int DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )
+{
+unsigned int i,j;
+//unsigned char *temp1,*temp2,
+unsigned char *sData;
+
+//Decode functino
+
+
+ //change by row
+// temp1 = (unsigned char*)malloc(CRYPT_ROW_SIZE);
+// temp2 = (unsigned char*)malloc(CRYPT_ROW_SIZE);
+ sData = (unsigned char*)malloc(data_len);
+ memcpy(sData,pData,data_len);
+
+ j = 1;
+ for ( i = 0 ; i < 32 ; i ++)
+ {
+ if ( j >= 32 )
+ j = 0;
+ memcpy(pData+(j*CRYPT_ROW_SIZE),sData+(i*CRYPT_ROW_SIZE),CRYPT_ROW_SIZE);
+ j += 2;
+ }
+
+ //replase by other word
+ for ( i = 0 ; i < data_len ; i++ )
+ {
+ *(pData+i) = getSBoxInvert(*(pData+i));
+ }
+
+ //mask by key
+ for ( i = 0 ; i < data_len ; i++ )
+ {
+ *(pData+i) ^=(*(key+(i%len_of_key)) );
+ }
+
+// free(temp1);
+// free(temp2);
+ free(sData);
+ return 0;
+}
+
+void * sqlite3Codec(void *pArg, void *pdata, Pgno nPageNum, int nMode)
+{
+LPCryptBlock pBlock;
+PgHdr *pageHeader;
+unsigned int dwPageSize = 0;
+unsigned char *data=(unsigned char *)(pdata);
+
+
+ pBlock = (LPCryptBlock)pArg;
+
+ if (!pBlock)
+ return data;
+
+ switch(nMode)
+ {
+ case 0: // Undo a "case 7" journal file encryption
+ case 2: //reload one page
+ case 3: //loading one page
+ if (!pBlock->ReadKey)
+ break;
+
+ dwPageSize = pBlock->PageSize;
+
+ DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );
+
+ break;
+
+ case 6: //Encrypt one page
+ if (!pBlock->WriteKey)
+ break;
+
+ memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
+ data = pBlock->Data + CRYPT_OFFSET;
+ dwPageSize = pBlock->PageSize;
+
+ Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE ); /*?£Y?[K*/
+
+ break;
+
+ case 7:
+ if (!pBlock->ReadKey)
+ break;
+
+ memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
+ data = pBlock->Data + CRYPT_OFFSET;
+ dwPageSize = pBlock->PageSize;
+
+ Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ); /*?£Y?[K*/
+
+ break;
+
+ }
+
+ return data;
+
+}
+
+
+//==========================
+static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting)
+{
+LPCryptBlock pBlock;
+
+ if (!pExisting)
+ {
+ pBlock =(CryptBlock *)sqlite3_malloc(sizeof(CryptBlock));
+
+ memset(pBlock, 0, sizeof(CryptBlock));
+ pBlock->ReadKey = hKey;
+ pBlock->WriteKey = hKey;
+ pBlock->PageSize = pager->pageSize;
+ pBlock->Data = (unsigned char*)sqlite3_malloc(pBlock->PageSize + CRYPT_OFFSET);
+ }
+ else
+ {
+ pBlock = pExisting;
+ if ( pBlock->PageSize != pager->pageSize && !pBlock->Data)
+ {
+ sqlite3_free(pBlock->Data);
+ pBlock->PageSize = pager->pageSize;
+ pBlock->Data = (unsigned char*)sqlite3_malloc(pBlock->PageSize + CRYPT_OFFSET);
+ }
+
+ }
+
+ memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);
+
+ return pBlock;
+
+}
+
+void sqlite3pager_set_codec(Pager *pPager,
+ void *(*xCodec)(void*,void*,Pgno,int),void *pCodecArg)
+{
+ pPager->xCodec = xCodec;
+ pPager->pCodec = pCodecArg;
+}
+
+
+static unsigned char *DeriveKey(const void *pKey, int nKeyLen)
+{
+unsigned char *hKey;
+
+ if( pKey == NULL || nKeyLen == 0 )
+ {
+ return NULL;
+ }
+
+ hKey = NULL;
+ hKey = (unsigned char *)sqlite3_malloc(DB_KEY_LENGTH_BYTE + 1);
+
+ if( hKey == NULL )
+ {
+ return NULL;
+ }
+
+ memset( hKey ,DB_KEY_PADDING, DB_KEY_LENGTH_BYTE + 1 );
+
+ hKey[DB_KEY_LENGTH_BYTE] = '\0';
+
+ if( nKeyLen < DB_KEY_LENGTH_BYTE )
+ {
+ memcpy( hKey, pKey, nKeyLen );
+ memcpy( (hKey+nKeyLen), pKey , (DB_KEY_LENGTH_BYTE-nKeyLen) );
+ }
+ else
+ {
+ memcpy( hKey, pKey, DB_KEY_LENGTH_BYTE );
+ }
+
+ return hKey;
+
+}
+
+
+static void * sqlite3pager_get_codecarg(Pager *pPager)
+{
+ return (pPager->xCodec) ? pPager->pCodec: NULL;
+}
+
+//======== getkey function.
+void sqlite3CodecGetKey(sqlite3 *db, int cnt, void **zKey, int *nKey)
+{
+ return ;
+}
+
+
+
+//======== rekey function.
+
+static void DestroyCryptBlock(LPCryptBlock pBlock)
+{
+ if (pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->ReadKey);
+ }
+
+ if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->WriteKey);
+ }
+
+ if(pBlock->Data)
+ {
+ sqlite3_free(pBlock->Data);
+ }
+
+ sqlite3_free(pBlock);
+
+}
+
+
+int sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize)
+{
+
+Btree *pbt = db->aDb[0].pBt;
+Pager *p = sqlite3BtreePager(pbt);
+LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);
+unsigned char * hKey = DeriveKey(pKey, nKeySize);
+int rc = SQLITE_ERROR;
+Pgno nPage;
+
+ if (!pBlock && !hKey)
+ return SQLITE_OK;
+
+ if (!pBlock)
+ {
+ pBlock = CreateCryptBlock(hKey, p, NULL);
+ pBlock->ReadKey = 0;
+ sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);
+
+ }
+ else
+ {
+ pBlock->WriteKey = hKey;
+ }
+
+
+ rc = sqlite3BtreeBeginTrans(pbt, 1);
+
+ if (!rc)
+ {
+
+ sqlite3PagerPagecount(p,&nPage);
+ Pgno nSkip = PAGER_MJ_PGNO(p);
+
+ void *pPage;
+ Pgno n;
+
+ for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
+ {
+ if (n == nSkip)
+ continue;
+
+ rc = sqlite3PagerGet(p, n, (DbPage **)&pPage);
+
+ if(!rc)
+ {
+ rc = sqlite3PagerWrite(pPage);
+ sqlite3PagerUnref(pPage);
+ }
+ }
+ }
+
+ if (!rc)
+ {
+ rc = sqlite3BtreeCommit(pbt);
+ }
+
+
+ if (rc)
+ {
+ sqlite3BtreeRollback(pbt,SQLITE_OK);
+ }
+
+ if (!rc)
+ {
+ if (pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->ReadKey);
+ }
+
+ pBlock->ReadKey = pBlock->WriteKey;
+
+ }
+ else
+ {
+ if (pBlock->WriteKey)
+ {
+ sqlite3_free(pBlock->WriteKey);
+ }
+
+ pBlock->WriteKey = pBlock->ReadKey;
+
+ }
+
+ if (!pBlock->ReadKey && !pBlock->WriteKey)
+ {
+ sqlite3pager_set_codec(p, NULL, NULL);
+ DestroyCryptBlock(pBlock);
+ }
+
+return rc;
+
+}
+
+int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)
+{
+ return sqlite3_rekey_interop(db, pKey, nKey);;
+}
+
+//======== acitvate see function.
+void sqlite3_activate_see(const char *zRight)
+{
+ return ;
+}
+
+
+//======== key function.
+
+
+int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *zKey, int nKey)
+{
+int rc;
+unsigned char *hKey;
+LPCryptBlock pBlock;
+
+ rc = SQLITE_ERROR;
+ if (db == NULL)
+ return rc;
+
+ hKey = 0;
+
+ if (!zKey || !nKey)
+ {
+ // not inpute code
+ if (!nDb)
+ {
+ return SQLITE_OK;
+ }
+ else
+ {
+ pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));
+ if (!pBlock)
+ return SQLITE_OK;
+
+ if (!pBlock->ReadKey)
+ return SQLITE_OK;
+
+ memcpy(pBlock->ReadKey, &hKey, 16);
+ }
+
+ }
+ else
+ {
+ hKey = DeriveKey(zKey, nKey);
+ }
+
+ if (hKey)
+ {
+ pBlock = CreateCryptBlock(hKey,sqlite3BtreePager(db->aDb[nDb].pBt), NULL);
+ sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock);
+
+ rc = SQLITE_OK;
+ }
+
+ return rc;
+}
+
+int sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)
+{
+ return sqlite3CodecAttach(db, 0, pKey, nKeySize);
+}
+
+int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)
+{
+ return sqlite3_key_interop(db, pKey, nKey);;
+}
+
+
+#endif
+
+
+/************** End of key.c *********************************************/
/************** Begin file attach.c ******************************************/
/*
** 2003 April 6
大功告成 , 接著 ...... 寫一個程式測試看看吧 ....... (下一篇..... )
Andorid 已經有使用sqlite 來超作資料庫,但是sqlite 沒有加密功能,所以只要自行處理 !!
不過 sqlite 有預留加密的進入點 !!
就一步一步來吧 !!
A.首先先打開 SQLITE_HAS_CODEC 這個 define.
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/Android.mk 2013-05-27 13:37:12.767651814 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/Android.mk 2013-05-24 18:55:23.884236340 +0800
@@ -27,7 +27,8 @@
-DSQLITE_OMIT_BUILTIN_TEST \
-DSQLITE_OMIT_COMPILEOPTION_DIAGS \
-DSQLITE_OMIT_LOAD_EXTENSION \
- -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600
+ -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600\
+ -DSQLITE_HAS_CODEC=1
common_src_files := sqlite3.c
B.Modify sqlite3.c file.
sqlite在編譯之前(Standard method) 會將所有 .c file 合併成為一個 .C file ( 我不知道為何要這樣 )
所以在BSP 內找到對應的檔案, 並且開始修改 !!
在 "Begin file attach.c" 之前開始插入修加密所需要的 code ;
詳細加密的功能可以參考下列網址 :
http://lancelot.blog.51cto.com/393579/940816
這網頁說的蠻清楚的 , 不過因為之前我們舊機種就已經有使用 (linux + GTK 架構 ) , 所以
就移植過來.
因為兩個版本不同,移植過來有些問題 , 所以需要修改一些小東西 , 可以參考下列網址 , 還蠻清楚的 !!
http://lancelot.blog.51cto.com/393579/940814
修改後的 diff 內容如下 , 不過太長加上有些機密問題 (加密方式 ) 所以我只列出一小部份:
diff -Nuraw TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/sqlite3.c TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/sqlite3.c
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/external/sqlite/dist/sqlite3.c 2013-05-27 13:37:12.802652106 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/external/sqlite/dist/sqlite3.c 2013-05-27 13:33:06.551572993 +0800
@@ -80395,6 +80395,501 @@
#endif /* SQLITE_OMIT_ANALYZE */
/************** End of analyze.c *********************************************/
+/************** Begin file key.c ******************************************/
+
+#ifdef SQLITE_HAS_CODEC
+
+//======== main codec function.
+typedef struct _CryptBlock
+{
+ char *ReadKey;
+ char *WriteKey;
+ int PageSize;
+ char *Data;
+
+} CryptBlock, *LPCryptBlock;
+
+#ifndef DB_KEY_LENGTH_BYTE
+ #define DB_KEY_LENGTH_BYTE 16
+#endif
+
+#ifndef DB_KEY_PADDING
..........
+#endif
+
+#define CRYPT_OFFSET 8
+#define CRYPT_ROW_SIZE 32
+
+int getSBoxValue(int num)
+{
.........................
+ return sbox[num];
+}
+
+int getSBoxInvert(int num)
+{
.................
+return rsbox[num];
+}
+
+int Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )
+{
+unsigned int i,j;
+//unsigned char *temp1,*temp2,
+unsigned char *sData;
+
+//Encode functino
............................
+ free(sData);
+ return 0;
+}
+
+int DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )
+{
+unsigned int i,j;
+//unsigned char *temp1,*temp2,
+unsigned char *sData;
+
+//Decode functino
+
+
+ //change by row
+// temp1 = (unsigned char*)malloc(CRYPT_ROW_SIZE);
+// temp2 = (unsigned char*)malloc(CRYPT_ROW_SIZE);
+ sData = (unsigned char*)malloc(data_len);
+ memcpy(sData,pData,data_len);
+
+ j = 1;
+ for ( i = 0 ; i < 32 ; i ++)
+ {
+ if ( j >= 32 )
+ j = 0;
+ memcpy(pData+(j*CRYPT_ROW_SIZE),sData+(i*CRYPT_ROW_SIZE),CRYPT_ROW_SIZE);
+ j += 2;
+ }
+
+ //replase by other word
+ for ( i = 0 ; i < data_len ; i++ )
+ {
+ *(pData+i) = getSBoxInvert(*(pData+i));
+ }
+
+ //mask by key
+ for ( i = 0 ; i < data_len ; i++ )
+ {
+ *(pData+i) ^=(*(key+(i%len_of_key)) );
+ }
+
+// free(temp1);
+// free(temp2);
+ free(sData);
+ return 0;
+}
+
+void * sqlite3Codec(void *pArg, void *pdata, Pgno nPageNum, int nMode)
+{
+LPCryptBlock pBlock;
+PgHdr *pageHeader;
+unsigned int dwPageSize = 0;
+unsigned char *data=(unsigned char *)(pdata);
+
+
+ pBlock = (LPCryptBlock)pArg;
+
+ if (!pBlock)
+ return data;
+
+ switch(nMode)
+ {
+ case 0: // Undo a "case 7" journal file encryption
+ case 2: //reload one page
+ case 3: //loading one page
+ if (!pBlock->ReadKey)
+ break;
+
+ dwPageSize = pBlock->PageSize;
+
+ DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );
+
+ break;
+
+ case 6: //Encrypt one page
+ if (!pBlock->WriteKey)
+ break;
+
+ memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
+ data = pBlock->Data + CRYPT_OFFSET;
+ dwPageSize = pBlock->PageSize;
+
+ Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE ); /*?£Y?[K*/
+
+ break;
+
+ case 7:
+ if (!pBlock->ReadKey)
+ break;
+
+ memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
+ data = pBlock->Data + CRYPT_OFFSET;
+ dwPageSize = pBlock->PageSize;
+
+ Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ); /*?£Y?[K*/
+
+ break;
+
+ }
+
+ return data;
+
+}
+
+
+//==========================
+static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting)
+{
+LPCryptBlock pBlock;
+
+ if (!pExisting)
+ {
+ pBlock =(CryptBlock *)sqlite3_malloc(sizeof(CryptBlock));
+
+ memset(pBlock, 0, sizeof(CryptBlock));
+ pBlock->ReadKey = hKey;
+ pBlock->WriteKey = hKey;
+ pBlock->PageSize = pager->pageSize;
+ pBlock->Data = (unsigned char*)sqlite3_malloc(pBlock->PageSize + CRYPT_OFFSET);
+ }
+ else
+ {
+ pBlock = pExisting;
+ if ( pBlock->PageSize != pager->pageSize && !pBlock->Data)
+ {
+ sqlite3_free(pBlock->Data);
+ pBlock->PageSize = pager->pageSize;
+ pBlock->Data = (unsigned char*)sqlite3_malloc(pBlock->PageSize + CRYPT_OFFSET);
+ }
+
+ }
+
+ memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);
+
+ return pBlock;
+
+}
+
+void sqlite3pager_set_codec(Pager *pPager,
+ void *(*xCodec)(void*,void*,Pgno,int),void *pCodecArg)
+{
+ pPager->xCodec = xCodec;
+ pPager->pCodec = pCodecArg;
+}
+
+
+static unsigned char *DeriveKey(const void *pKey, int nKeyLen)
+{
+unsigned char *hKey;
+
+ if( pKey == NULL || nKeyLen == 0 )
+ {
+ return NULL;
+ }
+
+ hKey = NULL;
+ hKey = (unsigned char *)sqlite3_malloc(DB_KEY_LENGTH_BYTE + 1);
+
+ if( hKey == NULL )
+ {
+ return NULL;
+ }
+
+ memset( hKey ,DB_KEY_PADDING, DB_KEY_LENGTH_BYTE + 1 );
+
+ hKey[DB_KEY_LENGTH_BYTE] = '\0';
+
+ if( nKeyLen < DB_KEY_LENGTH_BYTE )
+ {
+ memcpy( hKey, pKey, nKeyLen );
+ memcpy( (hKey+nKeyLen), pKey , (DB_KEY_LENGTH_BYTE-nKeyLen) );
+ }
+ else
+ {
+ memcpy( hKey, pKey, DB_KEY_LENGTH_BYTE );
+ }
+
+ return hKey;
+
+}
+
+
+static void * sqlite3pager_get_codecarg(Pager *pPager)
+{
+ return (pPager->xCodec) ? pPager->pCodec: NULL;
+}
+
+//======== getkey function.
+void sqlite3CodecGetKey(sqlite3 *db, int cnt, void **zKey, int *nKey)
+{
+ return ;
+}
+
+
+
+//======== rekey function.
+
+static void DestroyCryptBlock(LPCryptBlock pBlock)
+{
+ if (pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->ReadKey);
+ }
+
+ if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->WriteKey);
+ }
+
+ if(pBlock->Data)
+ {
+ sqlite3_free(pBlock->Data);
+ }
+
+ sqlite3_free(pBlock);
+
+}
+
+
+int sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize)
+{
+
+Btree *pbt = db->aDb[0].pBt;
+Pager *p = sqlite3BtreePager(pbt);
+LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);
+unsigned char * hKey = DeriveKey(pKey, nKeySize);
+int rc = SQLITE_ERROR;
+Pgno nPage;
+
+ if (!pBlock && !hKey)
+ return SQLITE_OK;
+
+ if (!pBlock)
+ {
+ pBlock = CreateCryptBlock(hKey, p, NULL);
+ pBlock->ReadKey = 0;
+ sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);
+
+ }
+ else
+ {
+ pBlock->WriteKey = hKey;
+ }
+
+
+ rc = sqlite3BtreeBeginTrans(pbt, 1);
+
+ if (!rc)
+ {
+
+ sqlite3PagerPagecount(p,&nPage);
+ Pgno nSkip = PAGER_MJ_PGNO(p);
+
+ void *pPage;
+ Pgno n;
+
+ for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
+ {
+ if (n == nSkip)
+ continue;
+
+ rc = sqlite3PagerGet(p, n, (DbPage **)&pPage);
+
+ if(!rc)
+ {
+ rc = sqlite3PagerWrite(pPage);
+ sqlite3PagerUnref(pPage);
+ }
+ }
+ }
+
+ if (!rc)
+ {
+ rc = sqlite3BtreeCommit(pbt);
+ }
+
+
+ if (rc)
+ {
+ sqlite3BtreeRollback(pbt,SQLITE_OK);
+ }
+
+ if (!rc)
+ {
+ if (pBlock->ReadKey)
+ {
+ sqlite3_free(pBlock->ReadKey);
+ }
+
+ pBlock->ReadKey = pBlock->WriteKey;
+
+ }
+ else
+ {
+ if (pBlock->WriteKey)
+ {
+ sqlite3_free(pBlock->WriteKey);
+ }
+
+ pBlock->WriteKey = pBlock->ReadKey;
+
+ }
+
+ if (!pBlock->ReadKey && !pBlock->WriteKey)
+ {
+ sqlite3pager_set_codec(p, NULL, NULL);
+ DestroyCryptBlock(pBlock);
+ }
+
+return rc;
+
+}
+
+int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)
+{
+ return sqlite3_rekey_interop(db, pKey, nKey);;
+}
+
+//======== acitvate see function.
+void sqlite3_activate_see(const char *zRight)
+{
+ return ;
+}
+
+
+//======== key function.
+
+
+int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *zKey, int nKey)
+{
+int rc;
+unsigned char *hKey;
+LPCryptBlock pBlock;
+
+ rc = SQLITE_ERROR;
+ if (db == NULL)
+ return rc;
+
+ hKey = 0;
+
+ if (!zKey || !nKey)
+ {
+ // not inpute code
+ if (!nDb)
+ {
+ return SQLITE_OK;
+ }
+ else
+ {
+ pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));
+ if (!pBlock)
+ return SQLITE_OK;
+
+ if (!pBlock->ReadKey)
+ return SQLITE_OK;
+
+ memcpy(pBlock->ReadKey, &hKey, 16);
+ }
+
+ }
+ else
+ {
+ hKey = DeriveKey(zKey, nKey);
+ }
+
+ if (hKey)
+ {
+ pBlock = CreateCryptBlock(hKey,sqlite3BtreePager(db->aDb[nDb].pBt), NULL);
+ sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock);
+
+ rc = SQLITE_OK;
+ }
+
+ return rc;
+}
+
+int sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)
+{
+ return sqlite3CodecAttach(db, 0, pKey, nKeySize);
+}
+
+int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)
+{
+ return sqlite3_key_interop(db, pKey, nKey);;
+}
+
+
+#endif
+
+
+/************** End of key.c *********************************************/
/************** Begin file attach.c ******************************************/
/*
** 2003 April 6
大功告成 , 接著 ...... 寫一個程式測試看看吧 ....... (下一篇..... )
2013年5月2日 星期四
Andorid HAL & system service testing / example code for TI AM335xevm JB BSP.
A. APP . "AndroInt_ext8_native"
We start from the demo apk. This apk is very simple , create two text input , and one button. Input the number at text_1 & text_2 , the button click will adding two numbers from each text, and show result on text of Button.
The IAndroIntServie is java interface , create by .aidl file in frameworks direct.
In this interface only have one function "AndroInt_add()".
So this using ServiceManage.getServie() to get system service.
This Service will implemnet in frameworks .
Now we go through to next step " modify frameworks ".
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java 2013-05-02 16:58:39.860415713 +0800
@@ -0,0 +1,87 @@
+package com.example.androInt_ext8_native;
+
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IAndroIntService;
+import android.os.ServiceManager;
+import android.os.RemoteException;
+
+//import android.os.Parcel;
+
+import android.util.Log;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.app.Activity;
+
+//import android.content.Context;
+
+
+public class MainActivity extends Activity implements OnClickListener
+{
+
+ private static final String TAG = "MainActivity";
+ private EditText mEditText2;
+ private EditText mEditText1;
+ private Button mButton;
+// private AndroIntService mAndroIntService = null ;
+
+ IAndroIntService om = IAndroIntService.Stub.asInterface(ServiceManager.getService("androint"));
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mEditText1 =(EditText) this.findViewById(R.id.editText1);
+ mEditText2 = (EditText) this.findViewById(R.id.editText2);
+ mButton = (Button) this.findViewById(R.id.button1);
+
+ mButton.setOnClickListener((android.view.View.OnClickListener) this);
+// mAndroIntService = new AndroIntService(this);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+
+ @Override
+ public void onClick(View v)
+ {
+ // TODO Auto-generated method stub
+ int result = 0 ;
+ int a = Integer.parseInt(mEditText1.getText().toString());
+ int b = Integer.parseInt(mEditText2.getText().toString());
+
+ Log.i(TAG, "a:" + a + " ,b:" + b );
+ Log.i(TAG, "om:" + om);
+
+ try
+ {
+// result = a + b ;
+ result = om.AndroInt_add(a, b);
+ Log.i(TAG, "result:" + result);
+ }
+ catch (RemoteException e)
+ {
+ // TODO Auto-generated catch block
+ Log.i(TAG, "Fail.... ");
+ }
+
+ mButton.setText(String.valueOf("A+B="+result ));
+
+ }
+
+}
+
+
+
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/Android.mk 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/Android.mk 2013-05-02 11:22:09.705661044 +0800
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := AndroInt_ext8_native
+
+include $(BUILD_PACKAGE)
B. Modify Frameworks .
1. Add new "IAndroIngService.aidl " into Android.mk file.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/Android.mk 2012-12-17 15:18:22.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/Android.mk 2013-04-30 16:25:22.118205204 +0800
@@ -126,6 +126,7 @@
core/java/android/nfc/INfcTag.aidl \
core/java/android/os/ICancellationSignal.aidl \
core/java/android/os/IHardwareService.aidl \
+ core/java/android/os/IAndroIntService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkManagementService.aidl \
core/java/android/os/IPermissionController.aidl \
2.Caeate "IAndroIntService.aidl " file. This interface only have one function.
"AndroInt_add()"
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/core/java/android/os/IAndroIntService.aidl TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/core/java/android/os/IAndroIntService.aidl
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/core/java/android/os/IAndroIntService.aidl 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/core/java/android/os/IAndroIntService.aidl 2013-04-30 16:25:15.269146567 +0800
@@ -0,0 +1,32 @@
+/*
+ * IAndroIntService.aidl
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+package android.os;
+
+/** {@hide} */
+interface IAndroIntService
+{
+ // obsolete flashlight support
+ int AndroInt_add(int a, int b);
+}
+
3.Implement AndroIntService.java file.
In this class , implement AndroInt_add(); function and
addService "androint" into system service.
In AndroInt_add() function , we call JNI function add_native().
The add_native() will access kernel driver.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/AndroIntService.java TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/AndroIntService.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/AndroIntService.java 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/AndroIntService.java 2013-05-02 13:58:21.110380956 +0800
@@ -0,0 +1,75 @@
+/*
+ * AndroIntService.java
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.IAndroIntService;
+import android.os.ServiceManager;
+import android.os.Message;
+import android.util.Slog;
+import android.util.Log;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class AndroIntService
+{
+
+ private static final String LOG_TAG = "AndroIntService";
+
+ private static native int init_native();
+ private static native int add_native(int a,int b);
+
+ private final Context mContext;
+
+ AndroIntService(Context context)
+ {
+ Log.i(LOG_TAG, "AndroIntService.");
+ init_native();
+ mContext = context;
+
+ Log.i(LOG_TAG, "addService.");
+ ServiceManager.addService("androint", mAndroInt_Bind);
+ }
+
+ private final IAndroIntService.Stub mAndroInt_Bind = new IAndroIntService.Stub()
+ {
+ public int AndroInt_add(int a , int b)
+ {
+ int result;
+ Log.i(LOG_TAG, "mAndroInt_Bind.AndroInt_add.");
+ result = add_native(a,b);
+ return result;
+ }
+
+ };
+
+
+
+
+
+}
4.Modif SystemService.java file .
When system service started, lunch AndroIntService Class and then
add service "androint" into system service.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/SystemServer.java TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/SystemServer.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/SystemServer.java 2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/SystemServer.java 2013-05-02 12:41:16.244678767 +0800
@@ -117,6 +117,7 @@
AccountManagerService accountManager = null;
ContentService contentService = null;
LightsService lights = null;
+ AndroIntService mAndroIntService = null;
PowerManagerService power = null;
BatteryService battery = null;
VibratorService vibrator = null;
@@ -208,6 +209,9 @@
Slog.i(TAG, "Lights Service");
lights = new LightsService(context);
+ Slog.i(TAG, "Testing Service");
+ mAndroIntService = new AndroIntService(context);
+
Slog.i(TAG, "Battery Service");
battery = new BatteryService(context, lights);
ServiceManager.addService("battery", battery);
@@ -657,7 +661,7 @@
} catch (Throwable e) {
reportWtf("starting CertBlacklister", e);
}
-
+
if (context.getResources().getBoolean(
com.android.internal.R.bool.config_enableDreams)) {
try {
5.Add jni cpp file into Android.mk file.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/Android.mk 2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/Android.mk 2013-04-30 16:25:20.077187730 +0800
@@ -8,6 +8,7 @@
com_android_server_input_InputManagerService.cpp \
com_android_server_input_InputWindowHandle.cpp \
com_android_server_LightsService.cpp \
+ com_android_server_AndroIntService.cpp \
com_android_server_PowerManagerService.cpp \
com_android_server_SerialService.cpp \
com_android_server_SystemServer.cpp \
6.Implement com_android_server_AndroIntService.cpp file.
There have two JNI function.
add_native(): write data into kernle char driver. And do add in kernel driver,
then read result from kernel char driver.
init_native(): get HAL module device data , and open kernel char device.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/com_android_server_AndroIntService.cpp TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/com_android_server_AndroIntService.cpp
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/com_android_server_AndroIntService.cpp 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/com_android_server_AndroIntService.cpp 2013-05-02 15:14:32.380259488 +0800
@@ -0,0 +1,98 @@
+/*
+ * com_android_server_AndroIntService.cpp
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#define LOG_TAG "AndroIntService_JNI"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <utils/misc.h>
+#include <utils/Log.h>
+#include <hardware/hardware.h>
+#include <hardware/androint.h>
+
+#include <stdio.h>
+
+namespace android
+{
+static hw_module_t *module;
+static hw_device_t *device ;
+
+ static jint add_native(JNIEnv *env, jobject clazz,int a , int b)
+ {
+ int result;
+ struct androint_device_t *int_dev;
+
+ ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+ if ( device == NULL )
+ {
+ ALOGI("[%s]:%d:Device is null \n",__FUNCTION__,__LINE__);
+ return (jint)-1;
+ }
+ else
+ {
+ int_dev = (struct androint_device_t *)device;
+ int_dev->write_add(int_dev,a,b);
+ result = int_dev->read_add(int_dev);
+ ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+
+ }
+ return (jint)result;
+ }
+
+ static jint init_native(JNIEnv *env, jobject clazz)
+ {
+ int err;
+
+ ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+ err = hw_get_module(ANDROINT_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+ if (err == 0)
+ {
+ err = module->methods->open(module, ANDROINT_HARDWARE_MODULE_ID, &device);
+ ALOGI("get module success! \n" );
+ }
+ else
+ {
+ device = NULL;
+ ALOGI("get module fail:%d! \n",err );
+ }
+
+ return (jint)err;
+ }
+
+ static JNINativeMethod method_table[] =
+ {
+ { "add_native", "(II)I", (void*)add_native },
+ { "init_native", "()I", (void*)init_native },
+ };
+
+ int register_android_server_AndroIntService(JNIEnv *env)
+ {
+ ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+ return jniRegisterNativeMethods(env, "com/android/server/AndroIntService",
+ method_table, NELEM(method_table));
+ }
+
+};
7.Modify onload.cpp file .
when system load .so module file. the "JNI_OnLoad" is first doing function.
In this function , we so register Natiye Metheods .
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/onload.cpp TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/onload.cpp
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/onload.cpp 2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/onload.cpp 2013-04-30 19:31:08.255261707 +0800
@@ -19,6 +19,8 @@
#include "utils/Log.h"
#include "utils/misc.h"
+#define LOG_TAG "onload"
+
namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_BatteryService(JNIEnv* env);
@@ -34,6 +36,9 @@
int register_android_server_SystemServer(JNIEnv* env);
int register_android_server_location_GpsLocationProvider(JNIEnv* env);
int register_android_server_connectivity_Vpn(JNIEnv* env);
+
+int register_android_server_AndroIntService(JNIEnv* env);
+
};
using namespace android;
@@ -64,5 +69,8 @@
register_android_server_location_GpsLocationProvider(env);
register_android_server_connectivity_Vpn(env);
+ ALOGI("register_android_server_AndroIntService...... ");
+ register_android_server_AndroIntService(env);
+
return JNI_VERSION_1_4;
}
C. Hard device side (HAL)
1. Create androint.h file.
In this file , define driver using stauct , called "androint_device_t"
And define HARDWARE_MODULE_ID "androint"
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/hardware/libhardware/include/hardware/androint.h TI-Android-JB-4.1.2_AM335x_4.0.1/hardware/libhardware/include/hardware/androint.h
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/hardware/libhardware/include/hardware/androint.h 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/hardware/libhardware/include/hardware/androint.h 2013-05-02 14:36:20.091463495 +0800
@@ -0,0 +1,54 @@
+/*
+ * androint.h
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ANDROIDINT_INTERFACE_H
+#define ANDROIDINT_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define ANDROINT_HARDWARE_MODULE_ID "androint"
+
+struct androint_device_t
+{
+ struct hw_device_t hw_dev;
+
+ int fd;
+ int (*write_add)(struct androint_device_t* dev,int a , int b );
+ int (*read_add)(struct androint_device_t* dev);
+};
+
+
+
+__END_DECLS
+
+#endif // ANDROID_LIGHTS_INTERFACE_H
+
2. Modify am335xevm_sd.mk file .
Add androin.$(TARGET_PRODUCE) .
### importent ###
androin.$(TARGET_PRODUCE) .
must same as HARDWARE_MODULE_ID
the HAL hw_get_module() will searce /system/lib/hw/ <id.product.board>
the id is HARDWARE_MODULE_ID.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/am335xevm_sk.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/am335xevm_sk.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/am335xevm_sk.mk 2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/am335xevm_sk.mk 2013-05-02 16:42:49.562787996 +0800
@@ -28,7 +28,8 @@
MagicSmokeWallpapers \
VisualizationWallpapers \
librs_jni \
- lights.$(TARGET_PRODUCT)
+ lights.$(TARGET_PRODUCT) \
+ androint.$(TARGET_PRODUCT)
PRODUCT_PROPERTY_OVERRIDES := \
net.dns1=8.8.8.8 \
3.Modify device.mk file .
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/device.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/device.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/device.mk 2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/device.mk 2013-05-02 16:42:51.695805279 +0800
@@ -112,6 +112,9 @@
hcitool
PRODUCT_PACKAGES += \
+ androint.am335xevm_sk
+
+PRODUCT_PACKAGES += \
lights.am335xevm_sk
PRODUCT_PACKAGES += \
4.Implement add.c file.
This file is driver access function.
open_add(): open device file of /dev/xxxxx . and setting read_add / write_add
function point into androint_device_t struct.
write_add()/read_add() : Direct access kernel device .
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/add.c TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/add.c
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/add.c 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/add.c 2013-05-02 16:46:04.784374408 +0800
@@ -0,0 +1,161 @@
+/*
+ * add.c
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#define LOG_TAG "HAL_add"
+
+#include <cutils/log.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <hardware/androint.h>
+
+
+#define DEVFILE "/dev/androint-1"
+
+
+static pthread_once_t g_init = PTHREAD_ONCE_INIT;
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static void init_globals(void)
+{
+ /* init the mutex */
+ pthread_mutex_init(&g_lock, NULL);
+}
+
+static int write_add(struct androint_device_t *dev, int a , int b )
+{
+int err;
+int buf[2];
+
+ ALOGI("Device:%s not open !!\n", DEVFILE);
+ err = -1;
+ if (dev->fd < 0 )
+ {
+ ALOGI("Device:%s not open !!\n", DEVFILE);
+ return err ;
+ }
+ pthread_mutex_lock(&g_lock);
+
+ buf[0] = a;
+ buf[1] = b;
+
+ err = write(dev->fd,buf,sizeof(int)*2);
+
+ pthread_mutex_unlock(&g_lock);
+
+ return err ;
+
+}
+
+static int read_add(struct androint_device_t* dev)
+{
+int err;
+int result;
+
+ err = -1;
+ if (dev->fd < 0 )
+ {
+ ALOGI("Device:%s not open !!\n", DEVFILE);
+ return err ;
+ }
+
+ pthread_mutex_lock(&g_lock);
+
+ read(dev->fd, &result,sizeof(int));
+
+ pthread_mutex_unlock(&g_lock);
+
+ return result;
+}
+
+static int close_add(struct androint_device_t *dev)
+{
+int err;
+ err = -1;
+ if (dev->fd > 0 )
+ {
+ ALOGI("Close %s\n", DEVFILE);
+ close(dev->fd);
+ dev->fd = -1 ;
+ err = 0;
+ }
+
+ return err;
+}
+
+static int open_add(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
+{
+struct androint_device_t *dev;
+
+ pthread_once(&g_init, init_globals);
+
+ dev = malloc(sizeof(struct androint_device_t));
+ memset(dev, 0, sizeof(*dev));
+
+ dev->hw_dev.tag = HARDWARE_DEVICE_TAG;
+ dev->hw_dev.version = 0;
+ dev->hw_dev.module = (struct hw_module_t *)module;
+ dev->hw_dev.close = (int (*)(struct hw_device_t *))close_add;
+
+ dev->fd = open(DEVFILE,O_RDWR);
+ dev->write_add = write_add;
+ dev->read_add = read_add;
+
+
+ ALOGI("Open %s\n", DEVFILE);
+
+ *device = (struct hw_device_t *)dev;
+
+ return 0;
+}
+
+static struct hw_module_methods_t add_module_methods =
+{
+ .open = open_add,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM =
+{
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = ANDROINT_HARDWARE_MODULE_ID,
+ .name = "Instant testing Module",
+ .author = "Instant, Inc.",
+ .methods = &add_module_methods,
+};
+
+
+
+
+
5.Create Andorid.mk file for build add.c .
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/Android.mk 1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/Android.mk 2013-05-02 16:58:00.966105273 +0800
@@ -0,0 +1,40 @@
+# Android.mk
+#
+# Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_PRODUCT),am335xevm_sk)
+# HAL module implemenation, not prelinked and stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := add.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := androint.$(TARGET_PRODUCT)
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
6.Modify init.am335xevm.rc file . to insmod kernel driver .ko file.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/init.am335xevm.rc TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/init.am335xevm.rc
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/init.am335xevm.rc 2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/init.am335xevm.rc 2013-05-02 15:02:15.438483092 +0800
@@ -43,6 +43,8 @@
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/mac80211.ko
insmod /system/lib/modules/wl12xx.ko
+ insmod /system/lib/modules/androint_module.ko
+
on fs
# Backlight
7.Modify uevnetd.am335xevm.rc file.
Change /dev/xxxxx group and owner.
diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/ueventd.am335xevm.rc TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/ueventd.am335xevm.rc
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/ueventd.am335xevm.rc 2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/ueventd.am335xevm.rc 2013-05-02 15:04:22.641516874 +0800
@@ -1 +1,2 @@
/dev/video0 0666 root root
+/dev/androint-1 0660 system system
D. Kernel Dirver
I am lazy to explain it, if have some question please contact me.
1.Makefile
# ./kernel/hardware/driver_test/Makefile
#
# vi: set ts=4 :
##=======================================
## Setting Compiler FLAGS.
##=======================================
export CFLAGS :=
export CPPFLAGS :=
export LDFLAGS :=
##==========================================
## Specital Make Rules.
##==========================================
KERNELDIR ?= $(PRJ_KERNEL_DIR)/_version
PWD := $(shell pwd)
ifeq ($(KERNELRELEASE),)
all:
@if [ -L '$(KERNELDIR)' ] ;then \
INSTALL_MOD_PATH=$(PRJ_IMG_DIR) $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) modules modules_install ;\
else \
$(MKMATE) color -fred "## Unknow kernel dir '$(KERNELDIR)', Please build kernel first...." ; \
exit 1 ; \
fi
distclean clean:
@rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions [mM]odule*
else
obj-m := androint_module.o
endif
2.Driver code.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#define DEV_MAJOR 48
#define DEV_NAME "androint"
struct androint_dev
{
int data[2];
struct cdev cdev;
struct class *sysfs_class;
dev_t dev_num;
};
struct androint_dev androint_device;
ssize_t androint_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
ssize_t retval;
int sum ;
retval = 0;
sum = androint_device.data[0] + androint_device.data[1];
if (count != sizeof (int))
{
printk(KERN_INFO "Read error: buffer size not same !\n");
goto out;
}
retval = copy_to_user(buf,&sum , sizeof(int));
if ( retval)
retval = -EFAULT;
out:
return retval;
}
ssize_t androint_write(struct file *filp, const char *buf, size_t count,
loff_t *f_pos)
{
ssize_t retval;
retval = 0;
if (count != sizeof(int) * 2 )
{
printk(KERN_INFO "Write error: buffer size not same !\n");
goto out;
}
retval = copy_from_user(androint_device.data , buf, count);
if ( retval)
retval = -EFAULT;
out:
return retval;
}
int androint_open(struct inode *inode, struct file *filp)
{
int num = MINOR(inode->i_rdev);
printk("androint_open -> minor : %d\n", num);
return 0;
}
int androint_release(struct inode *inode, struct file *filp)
{
printk("androint_release \n");
return 0;
}
struct file_operations androint_fops =
{
.owner = THIS_MODULE,
.read = androint_read,
.write = androint_write,
.open = androint_open,
.release = androint_release,
};
static int __init androint_init(void)
{
int result;
printk(KERN_INFO "Module inti starts !\n");
androint_device.dev_num = MKDEV(DEV_MAJOR,0);
result = register_chrdev_region(androint_device.dev_num,1, DEV_NAME);
if (result < 0)
{
printk( KERN_ALERT "androint: cannot register device region of %s\n",DEV_NAME);
return result;
}
cdev_init(&androint_device.cdev, &androint_fops);
androint_device.cdev.owner = THIS_MODULE;
result = cdev_add(&androint_device.cdev,androint_device.dev_num,1);
if (result)
{
printk(KERN_INFO "Can not add device %s \n ", DEV_NAME);
goto fail_addcdev;
}
// populate sysfs entry
androint_device.sysfs_class = class_create(THIS_MODULE, DEV_NAME);
device_create(androint_device.sysfs_class, NULL,
androint_device.dev_num, NULL, DEV_NAME"-%d", 1);
printk(KERN_INFO "Module inti done !\n");
fail_addcdev:
unregister_chrdev_region(androint_device.dev_num,1);
return result;
}
void androint_exit(void)
{
// remove the cdev
cdev_del(&androint_device.cdev);
// Freeing the major number
unregister_chrdev_region(androint_device.dev_num, 1);
device_destroy(androint_device.sysfs_class, androint_device.dev_num);
class_destroy(androint_device.sysfs_class);
printk(KERN_INFO "Module release done !\n");
}
module_init(androint_init);
module_exit(androint_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Instnat");
訂閱:
意見 (Atom)