android.bp文件内容:
// Copyright 2013 The Android Open Source Project
cc_binary {
name: "mytest",
srcs: ["mytest.c", ],
shared_libs: [
"liblog",
"libcutils",
],
static_libs: [
"libstatslogc",
"libstatssocket",
],
local_include_dirs: ["include","libs",],
cflags: ["-Werror", "-DLMKD_TRACE_KILLS", "-DUSE_UEVENT","-Werror","-Wunused-parameter"],
product_variables: {
use_lmkd_stats_log: {
cflags: [
"-DLMKD_LOG_STATS"
],
},
},
}
测试程序内容:
将在/system/bin/下生成elf可执行的二进制文件
#define LOG_TAG "mytest"
#include <errno.h>
#include <inttypes.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <lmkd.h>
#include <log/log.h>
#ifdef LMKD_LOG_STATS
#include "statslog.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <pthread.h>
#include <limits.h>
#include <stdarg.h>
#include <ctype.h>
#include <assert.h>
#include <linux/input.h>
#include <cutils/sockets.h>
#include <cutils/properties.h>
#include <cutils/android_reboot.h>
#include <cutils/klog.h>
#include <utils/Log.h>
#include <android/log.h>
#include <syslog.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <sys/poll.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include "usrlink.h"
#include "apk_change_key.h"
#include "htfsk.h"
#include "debug.h"
#include "file_op.h"
#include "util.h"
#include "keyboard.h"
#include "version.h"
#include "factory_set.h"
#include "htfsk.h"
int debug_msg(const char *format, ...)
{
FILE *fp;
unsigned int send_len;
char *tmpbuf = malloc(8192);
fp = fopen("/dev/ttyS0", "wb" );
if( tmpbuf == NULL ){
return -1;
}
va_list vArgs;
va_start(vArgs, format);
vsnprintf( (char *)&tmpbuf[0], 8192, (char const *)format, vArgs );
va_end(vArgs);
send_len = strlen(&tmpbuf[0]);
fwrite(tmpbuf, 1, send_len, fp);
//__android_log_write( ANDROID_LOG_DEBUG, TAG, tmpbuf );
if( tmpbuf != NULL ){
free(tmpbuf);
}
fclose(fp);
return 0;
}
#define RESULT_MAX_BUFF_SIZE 4096
int exec_cmd_and_get_result( const char *cmd_str, char *buffer )
{
int cnt;
FILE *pf;
pf = popen(cmd_str, "r");
cnt=fread(buffer, 1,RESULT_MAX_BUFF_SIZE, pf);
buffer[cnt-1] = '\0';
printf( "fread cnt = %d\n", cnt );
//printf( "strlen(buffer) = %d\n", strlen(buffer) );
printf( "buffer = %s\n", buffer );
pclose(pf);
return 0;
}
int do_create_thread(func_pointer thread_func, void *arg)
{
int Threaderr, ret;
pthread_attr_t attr;
pthread_t tmp_thread_id;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Threaderr = pthread_create( &tmp_thread_id, NULL, thread_func, arg );
ret = pthread_detach( tmp_thread_id );
if( Threaderr != 0 ){
debug_msg("pthread_create error.\n");
}
return tmp_thread_id;
//当线程为joinable时,使用pthread_join来获取线程返回值,并释放资源
//当线程为非joinable时,也可在线程中调用 pthread_detach(pthread_self())来分离自己
}
int is_file_exist(const char *file_path)
{
if( file_path == NULL ){
return -1;
}
if( access(file_path, F_OK) == 0 ){
return 0;
}else{
return -2;
}
}
static int is_dir_exist(const char *dir_path)
{
DIR *dp;
dp = NULL;
if( dir_path == NULL ){
return -1;
}
if( (dp = opendir(dir_path)) == NULL ){
return -2;
}else{
closedir(dp);
return 0;
}
}
int cpu_get_lltimer( struct timeval* tv )
{
int retval;
retval = gettimeofday( tv, NULL );
if( retval != 0 ){
printf("get time err\r\n");
}
return retval;
}
unsigned int cpu_diff_us( struct timeval *tv )
{
int retval;
struct timeval currentv;
unsigned int timediff = 0;
retval = gettimeofday(¤tv,NULL);
if( retval != 0 ){
printf("get time err\r\n");
return 0xffffffff;
}
timediff = (currentv.tv_sec - tv->tv_sec)*1000000;
timediff += (currentv.tv_usec - tv->tv_usec);
return timediff;
}
struct timeval power_key_timestamp;
int power_key_pressed()
{
cpu_get_lltimer(&power_key_timestamp);
return 0;
}
void *main_key( void *arg __unused );
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if.h>
#define Ser_Printf printf
#define macdbg_prser printf
int macdbg_dmphex(const char* buff, int len)
{
int retval = 0;
int x, y, tot, lineoff;
const char* curr;
//Ser_Printf("buff %x.\r\n", buff );
Ser_Printf("\r\n" );
lineoff = 0;
curr = buff;
tot = 0;
for( x = 0; x+16 < len; ){
Ser_Printf("%x\t", lineoff);
for( y = 0; y < 16; y++ ){
macdbg_prser("%02x ", (unsigned char)*(curr + y));
}
macdbg_prser(" ");
for( y = 0; y < 16; y++ ){
char c;
c = *(curr + y);
if( c > 31 && c < 127 ){
macdbg_prser("%c", c);
}else{
macdbg_prser("%c", '.');
}
tot++;
}
curr += 16;
x += 16;
lineoff+=16;
macdbg_prser("\r\n");
}
//do last line
//Ser_Printf("tot %d.\r\n", tot );
//Ser_Printf("len %d.\r\n", len );
if( tot < len ){
curr = (buff + tot);
macdbg_prser("%x\t", lineoff);
for( y = 0; y < (len - tot); y++ ){
macdbg_prser("%02x ", (unsigned char)*(curr + y));
}
//padding with spaces
//Ser_Printf("(len - tot) %d.\r\n", (len - tot) );
if( (len - tot) < 16 ){
for( y = 0; y < (32 - ((len - tot)*2)); y++ ){
macdbg_prser(" ");
}
}
for( y = 0; y < 16-(len - tot); y++ ){
macdbg_prser(" ");
}
macdbg_prser(" ");
//Ser_Printf("(len - tot) %d.\r\n", (len - tot) );
for( y = 0; y < (len - tot); y++ ){
char c;
c = *(curr + y);
if( c >31 && c < 127 ){
macdbg_prser("%c", c);
}else{
macdbg_prser("%c", '.');
//macdbg_prser("%c", c);
}
}
}
macdbg_prser("\r\n");
return retval;
}
#define BUFLEN 20480
int main(int argc __unused, char *argv[] __unused)
{
int fd, retval;
char buf[BUFLEN] = {0};
int len = BUFLEN;
struct sockaddr_nl addr;
struct nlmsghdr *nh;
struct rtattr *attr;
fd_set rd_set;
struct timeval timeout;
int select_r;
// 1. 打开 NetLink Socket
// 第一个参数必须是AF_NETLINK或PF_NETLINK, 在Linux中, 它们俩实际为一个东西, 它表示要使用netlink
// 第二个参数必须是SOCK_RAW或SOCK_DGRAM
// 第三个参数指定netlink协议类型, NETLINK_ROUTE 意为“路由守护进程”
// 绑定该协议所创建出来的fd可以接收到来自内核的路由通知事件(如网路接口eth0上线)
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
// 2. 设定接收类型并绑定Socket
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
// 指定接收路由多播组消息 + IPV4消息
addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
// bind()用于把一个打开的netlink socket与netlink源socket地址绑定在一起
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
while(1){
//每次循环都要清空集合,否则不能检测描述符变化
FD_ZERO(&rd_set);
//添加描述符
FD_SET(fd, &rd_set);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
// read()函数读不到东西会一直阻塞, 用select()函数可以达到不阻塞的效果
// select()能够监视我们需要监视的文件描述符的变化情况——读写或是异常
// 此处select()监视到fd可读之后, 返回值select_r大于0; fd不可读, 则返回0
select_r = select(fd + 1, &rd_set, NULL, NULL, &timeout);
if( select_r < 0 ){
printf("select() return error\n");
}else if(select_r > 0){
if( FD_ISSET(fd, &rd_set) ){
retval = read(fd, buf, BUFLEN);
//printf("retval = %d\n", retval);
//printf("buf1 = %s\n", buf);
//macdbg_dmphex(buf, retval);
for(nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, (unsigned)retval); nh = NLMSG_NEXT(nh, retval)){
if(nh->nlmsg_type == NLMSG_DONE)
break;
else if(nh->nlmsg_type == NLMSG_ERROR)
return 1;
else if(nh->nlmsg_type == RTM_NEWLINK)
{
struct ifinfomsg *ifinfo;
ifinfo = NLMSG_DATA(nh);
printf("NEWLINK: %s", (ifinfo->ifi_flags & IFF_LOWER_UP) ? "up" : "down");
attr = (struct rtattr*)(((char*)nh) + NLMSG_SPACE(sizeof(*ifinfo)));
len = nh->nlmsg_len - NLMSG_SPACE(sizeof(*ifinfo));
for(; RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
{
if(attr->rta_type == IFLA_IFNAME)
{
printf(" %s", (char*)RTA_DATA(attr));
break;
}
}
printf("\n");
}
else if(nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR)
{
struct ifaddrmsg *ifaddr;
ifaddr = NLMSG_DATA(nh);
printf("%s:", (nh->nlmsg_type==RTM_NEWADDR)?"NEWADDR":"DELADDR");
attr = (struct rtattr*)(((char*)nh) + NLMSG_SPACE(sizeof(*ifaddr)));
len = nh->nlmsg_len - NLMSG_SPACE(sizeof(*ifaddr));
for(; RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
{
if(attr->rta_type == IFA_ADDRESS)
{
char tmp[32] = {0};
inet_ntop(ifaddr->ifa_family, RTA_DATA(attr), tmp, sizeof(tmp));
printf(" %s", tmp);
}
if(attr->rta_type == IFA_LABEL)
{
printf(" %s", (char*)RTA_DATA(attr));
break;
}
}
printf("\n");
}
}
}
}
}
close(fd);
return 0;
}
程序运行结果:
[ 478.088963] r8152 2-1:1.0 eth0: carrier on
NEWLINK: up eth0
NEWADDR: 192.168.0.108 eth0
NEWLINK: down eth0
DELADDR: 192.168.0.108 eth0