adb push out/target/product/generic_x86_64/system/bin/godvserver data/local
adb push out/target/product/generic_x86_64/system/bin/godvclient data/local
cmds/servicemanager/godv_server.c
/* Copyright 2008 The Android Open Source Project
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "binder.h"
#include "godv_server.h"
void sayhello(void)
{
static int cnt = 0;
fprintf(stderr, "sayhello : %d\n",cnt++);
}
int sayhello_to(char *name)
{
static int cnt = 9002;
fprintf(stderr, "sayhello_to %s : %d\n",name,cnt++);
return cnt;
}
int godv_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
fprintf(stderr, "godv_handler\n");
//根據txn->code知道要調用哪個函數
//如果需要參數可以從*msg中取
//傳回結果*reply
//提供兩個參數 一個sayhello 一個sayhelloto
uint16_t *s;
size_t len;
uint32_t strict_policy;
struct binder_state *bd;
bd = bs;
strict_policy = bio_get_uint32(msg);
/*s = bio_get_string16(msg, &len);
if (s == NULL) {
fprintf(stderr, "s == NULL\n");
return -1;
}*/
char name[512];
unsigned i;
int b;
switch(txn->code) {
case HELLO_SVR_CMD_SAYHELLO:
sayhello();
return 0;
case HELLO_SVR_CMD_SAYHELLO_TO:
//從*msg中取出字元串
s = bio_get_string16(msg, &len);
if (s == NULL) {
fprintf(stderr, "case s == NULL\n");
return -1;
}
for(i = 0; i < len; i++){
name[i] = s[i];
}
name[i] = '\0';
//調用函數
b = sayhello_to(name);
//傳回結果
bio_put_uint32(reply, b);
break;
default:
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
uint32_t handle;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
return 0;
handle = bio_get_ref(&reply);
if (handle)
binder_acquire(bs, handle);
binder_done(bs, &msg, &reply);
return handle;
}
int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
int status;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
bio_put_obj(&msg, ptr);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
return -1;
status = bio_get_uint32(&reply);
binder_done(bs, &msg, &reply);
return status;
}
unsigned token;
int main(int argc, char **argv)
{
struct binder_state *bs;
uint32_t svcmgr = BINDER_SERVICE_MANAGER;
//1打開驅動
bs = binder_open("/dev/binder", 128*1024);
if (!bs) {
fprintf(stderr, "failed to open binder driver\n");
return -1;
}
int ret;
//傳回值 0 代表成功
//2add server 目标服務 服務名稱
ret = svcmgr_publish(bs, svcmgr, "godv", (void *)9002);
if (ret) {
fprintf(stderr, "failed to publish godv service\n");
return -1;
}
fprintf(stderr, "success to publish godv service\n");
ret = svcmgr_publish(bs, svcmgr, "goda", (void *)9003);
if (ret) {
fprintf(stderr, "failed to publish goda service\n");
}
fprintf(stderr, "success to publish goda service\n");
//循環 讀資料 解析資料 處理資料 回複
binder_loop(bs, godv_handler);
argc--;
argv++;
return 0;
}
cmds/servicemanager/godv_server.h
#ifndef _GODV_SERVER_H
#define _GODV_SERVER_H
#define HELLO_SVR_CMD_SAYHELLO 0
#define HELLO_SVR_CMD_SAYHELLO_TO 1
#endif
cmds/servicemanager/godv_client.c
/* Copyright 2008 The Android Open Source Project
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "binder.h"
#include "godv_server.h"
uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
uint32_t handle;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
return 0;
handle = bio_get_ref(&reply);
if (handle)
binder_acquire(bs, handle);
binder_done(bs, &msg, &reply);
return handle;
}
int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
int status;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
bio_put_obj(&msg, ptr);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
return -1;
status = bio_get_uint32(&reply);
binder_done(bs, &msg, &reply);
return status;
}
struct binder_state *g_bs;
uint32_t g_handle;
void sayhello(void)
{
//構造binder_io
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
//放入參數
//無
//調用binder_call
if (binder_call(g_bs, &msg, &reply, g_handle, HELLO_SVR_CMD_SAYHELLO)){
fprintf(stderr, "failed to binder_call godv server\n");
}
//用replay讀取參數
//處理完畢
binder_done(g_bs, &msg, &reply);
}
int sayhello_to(char *name)
{
//構造binder_io
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
//放入參數
bio_put_string16_x(&msg, name);
//調用binder_call
if (binder_call(g_bs, &msg, &reply, g_handle, HELLO_SVR_CMD_SAYHELLO_TO))
return 0;
//用replay讀取參數
int ret;
ret = bio_get_uint32(&reply);
//處理完畢
binder_done(g_bs, &msg, &reply);
return ret;
}
int main(int argc, char **argv)
{
if(argc < 2){
fprintf(stderr, "Usage:\n");
fprintf(stderr, "%s hello\n",argv[0]);
fprintf(stderr, "%s hello <name>\n",argv[0]);
}
struct binder_state *bs;
uint32_t svcmgr = BINDER_SERVICE_MANAGER;
uint32_t handle;
bs = binder_open("/dev/binder", 128*1024);
if (!bs) {
fprintf(stderr, "failed to open binder driver\n");
return -1;
}
g_bs = bs;
//1 getservice
//向servicemanager
//擷取名為godv的服務
handle = svcmgr_lookup(bs, svcmgr, "godv");
g_handle = handle;
if(!handle)
{
fprintf(stderr, "failed to get godv service\n");
return -1;
}
//2 發送資料
/*
假設程式的名稱為prog,
當隻輸入prog,則由作業系統傳來的參數為:
argc=1,表示隻有一程式名稱。
argc隻有一個元素,argv[0]指向輸入的程式路徑及名稱:./prog
當輸入prog para_1,有一個參數,則由作業系統傳來的參數為:
argc=2,表示除了程式名外還有一個參數。
argv[0]指向輸入的程式路徑及名稱。
argv[1]指向參數para_1字元串。
當輸入prog para_1 para_2 有2個參數,則由作業系統傳來的參數為:
argc=3,表示除了程式名外還有2個參數。
argv[0]指向輸入的程式路徑及名稱。
argv[1]指向參數para_1字元串。
argv[2]指向參數para_2字元串。*/
int ret;
if(argc == 2) { //輸入 ./godv_client xxx
//sayhello
sayhello();
} else if (argc == 3){ //輸入 ./godv_client xxx xxx
//sayhello_to
ret = sayhello_to(argv[2]);
fprintf(stderr, "get ret of sayhello_to = %d\n",ret);
}
//釋放
binder_release(bs, handle);
return 0;
}
cmds/servicemanager/Android.bp
cc_defaults {
name: "servicemanager_flags",
cflags: [
"-Wall",
"-Wextra",
"-Werror",
],
product_variables: {
binder32bit: {
cflags: ["-DBINDER_IPC_32BIT=1"],
},
},
shared_libs: ["liblog"],
}
cc_binary {
name: "bctest",
defaults: ["servicemanager_flags"],
srcs: [
"bctest.c",
"binder.c",
],
}
cc_binary {
name: "servicemanager",
defaults: ["servicemanager_flags"],
srcs: [
"service_manager.c",
"binder.c",
],
shared_libs: ["libcutils", "libselinux"],
init_rc: ["servicemanager.rc"],
}
cc_binary {
name: "vndservicemanager",
defaults: ["servicemanager_flags"],
vendor: true,
srcs: [
"service_manager.c",
"binder.c",
],
cflags: [
"-DVENDORSERVICEMANAGER=1",
],
shared_libs: ["libcutils", "libselinux_vendor"],
init_rc: ["vndservicemanager.rc"],
}
cc_binary {
name: "godvserver",
defaults: ["servicemanager_flags"],
srcs: [
"godv_server.c",
"binder.c",
],
}
cc_binary {
name: "godvclient",
defaults: ["servicemanager_flags"],
srcs: [
"godv_client.c",
"binder.c",
],
}