#include #include #include #include #include #include #include #include #include "rk_mpi_mmz.h" using namespace android; #define BINDER_SERV_NAME "MPI_MMZ_DEMO" void assert_fail(const char *file, int line, const char *func, const char *expr) { printf("assertion failed at file %s, line %d, function %s:\n", file, line, func); printf("%s\n", expr); abort(); } #define ASSERT(e) \ do { \ if (!(e)) \ assert_fail(__FILE__, __LINE__, __func__, #e); \ } while(0) // Interface (our AIDL) - Shared by server and client class IDemo : public IInterface { public: enum { GET_BUFFER = IBinder::FIRST_CALL_TRANSACTION, SET_BUFFER, FREE_BUFFER, }; virtual void setBuffer(int32_t fd, uint32_t len) = 0; virtual void getBuffer(int32_t* fd, uint32_t* len) = 0; virtual void freeBuffer() = 0; DECLARE_META_INTERFACE(Demo); }; // Client class BpDemo : public BpInterface { public: explicit BpDemo(const sp& impl) : BpInterface(impl) { printf("BpDemo::BpDemo()\n"); } virtual void setBuffer(int32_t fd, uint32_t len) { Parcel data, reply; data.writeInterfaceToken(IDemo::getInterfaceDescriptor()); data.writeFileDescriptor(fd); data.writeUint32(len); remote()->transact(SET_BUFFER, data, &reply); printf("BpDemo::setBuffer(fd=%d, len=%u)\n", fd, len); } virtual void getBuffer(int32_t* fd, uint32_t* len) { Parcel data, reply; data.writeInterfaceToken(IDemo::getInterfaceDescriptor()); remote()->transact(GET_BUFFER, data, &reply); // 注意:这里有次dup fd *fd = dup(reply.readFileDescriptor()); *len = reply.readUint32(); printf("BpDemo::getBuffer(fd=%d, len=%u)\n", *fd, *len); } virtual void freeBuffer() { Parcel data; data.writeInterfaceToken(IDemo::getInterfaceDescriptor()); remote()->transact(FREE_BUFFER, data, NULL); printf("BpDemo::freeBuffer()\n"); } }; IMPLEMENT_META_INTERFACE(Demo, BINDER_SERV_NAME); // Server class BnDemo : public BnInterface { virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; status_t BnDemo::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { data.checkInterface(this); switch(code) { case SET_BUFFER: { int32_t fd = data.readFileDescriptor(); uint32_t len = data.readUint32(); // 注意:这里有次dup fd setBuffer(dup(fd), len); return NO_ERROR; } break; case GET_BUFFER: { int32_t fd; uint32_t len; getBuffer(&fd, &len); ASSERT(reply != 0); reply->writeFileDescriptor(fd); reply->writeUint32(len); return NO_ERROR; } break; case FREE_BUFFER: { freeBuffer(); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } /* 相同返回 0 不同返回 -1 */ int check_data(uint8_t *data, uint8_t value, uint32_t len) { for(uint32_t i=0; i getDemoServ() { sp sm = defaultServiceManager(); ASSERT(sm != 0); sp binder = sm->getService(String16(BINDER_SERV_NAME)); // TODO: If the "Demo" service is not running, getService times out and binder == 0. ASSERT(binder != 0); sp ret = interface_cast(binder); ASSERT(ret != 0); return ret; } void startDemoServ() { defaultServiceManager()->addService(String16(BINDER_SERV_NAME), new Server()); android::ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); printf("service is now ready\n"); } sp demo; MB_BLK dequeue() { int fd = -1; uint32_t len = 0; demo->getBuffer(&fd, &len); if (fd < 0) return (MB_BLK)NULL; demo->freeBuffer(); MB_BLK blk = RK_MPI_MMZ_ImportFD(fd, len); return blk; } void queue(MB_BLK blk) { uint32_t len = RK_MPI_MMZ_GetSize(blk); int fd = RK_MPI_MMZ_Handle2Fd(blk); // 把buffer送入server demo->setBuffer(fd, len); // 释放client端内存 RK_MPI_MMZ_Free(blk); } int main(int argc, char **argv) { (void)argv; if (argc == 1) { printf("=== server PID[%d] ===\n", getpid()); startDemoServ(); } else if (argc == 2) { printf("=== client PID[%d] ===\n", getpid()); demo = getDemoServ(); // 从Server取出一块buffer MB_BLK blk = dequeue(); if (blk == NULL) { printf("dequeue buffer fail!\n"); return -1; } // 检查数据正确性,预期是全部 0x5A void* vaddr = RK_MPI_MMZ_Handle2VirAddr(blk); uint32_t len = RK_MPI_MMZ_GetSize(blk); if (check_data((uint8_t*)vaddr, 0x5A, len) == 0) { printf("check okay.\n"); } else { printf("check fail.\n"); } printf("Press Enter key to continue...\n");getchar(); // 更新数据 printf("Fill 0x3C\n"); memset(vaddr, 0x3C, len); // 把内存还给server queue(blk); printf("Press Enter key to quit...\n");getchar(); } return 0; }