赞
踩
├── js
│ └── napi // js 和 c++ 通信
│ ├── inc
│ └── src
└── native
├── c_adapter
│ ├── inc
│ └── src
├── include
├── interfaces
└── src
communication\wifi\interfaces\innerkits\native_cpp\napi\wifi_napi_entry.cpp namespace OHOS { namespace Wifi { #ifndef ENABLE_NAPI_COMPATIBLE /* * Module initialization function */ static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("enableWifi", EnableWifi), // DECLARE_NAPI_FUNCTION("disableWifi", DisableWifi), DECLARE_NAPI_FUNCTION("isWifiActive", IsWifiActive), // ... 绑定函数 }; // 将desc中设置到export中 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc)); return exports; } // 1. 创建module static napi_module wifiJsModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = NULL, .nm_register_func = Init, // 2. 注册函数表 .nm_modname = "wifi", // module name .nm_priv = ((void *)0), .reserved = { 0 } }; // 3. 注册module extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&wifiJsModule); } } // namespace Wifi } // namespace OHOS
napi_value EnableWifi(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiDevicePtr != nullptr, "Wifi device instance is null.");
ErrCode ret = wifiDevicePtr->EnableWifi();
WriteWifiStateHiSysEvent(HISYS_SERVICE_TYPE_STA, WifiOperType::ENABLE);
napi_value result;
napi_get_boolean(env, ret == WIFI_OPT_SUCCESS, &result);
return result;
}
/** * Provides methods to operate or manage Wi-Fi. * * @since 6 * @import import wifi from '@ohos.wifi'; */ declare namespace wifi { function enableWifi(): boolean; function disableWifi(): boolean; function isWifiActive(): boolean; function scan(): boolean; function getScanInfos(): Promise<Array<WifiScanInfo>>; // ... } export default wifi;
OpenHarmony 源码解析之JavaScript API框架(NAPI)-开源基础软件社区-51CTO.COM
#过年不停更# Openharmony IPC通信(L2)-开源基础软件社区-51CTO.COM
Remote() 封装的 binder 通信
Android | OHOS |
---|---|
SeviceManager管理 | SystemAbilityManagerClient管理 |
service自己注册到binder | 需要手动注册到binder |
只需要关注方法和参数,其余aidl自动生成 | 需要自己手写逻辑 |
// 客户端发请求 @Override public void addPerson(Person person) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(DESCRIPTOR);// 1. 写入binder标识 if (null != person) { data.writeInt(1); person.writeToParcel(data, 0); // 2. 写入数据 } else { data.writeInt(0); } mRemote.transact(TRANSACTION_addPerson, data, reply, 0);// 3. 发消息 reply.readException(); } finally { data.recycle(); reply.recycle(); } } // 服务端接收请求 protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException { switch (code) { case INTERFACE_TRANSACTION: reply.writeString(DESCRIPTOR); return true; case TRANSACTION_addPerson: data.enforceInterface(DESCRIPTOR); Person arg0; if (0 != data.readInt()) { arg0 = (Person) Person.CREATOR.createFromParcel(data); } else { arg0 = null; } this.addPerson(arg0); reply.writeNoException(); return true; case TRANSACTION_getPersonList: data.enforceInterface(DESCRIPTOR); List<Person> result = getPersonList(); reply.writeNoException(); reply.writeTypedList(result); return true; } return super.onTransact(code, data, reply, flags); }
// 发送请求 ErrCode WifiDeviceProxy::EnableWifi() { if (mRemoteDied) { WIFI_LOGE("failed to `%{public}s`,remote service is died!", __func__); return WIFI_OPT_FAILED; } MessageOption option; MessageParcel data; MessageParcel reply; //1. 写入binder标识 // DECLARE_INTERFACE_DESCRIPTOR(u"ohos.wifi.IWifiDeviceService"); if (!data.WriteInterfaceToken(GetDescriptor())) { WIFI_LOGE("Write interface token error: %{public}s", __func__); return WIFI_OPT_FAILED; } //2. 写入数据 data.WriteInt32(0); //3. 向服务端发消息 WIFI_SVR_CMD_ENABLE_WIFI int error = Remote()->SendRequest(WIFI_SVR_CMD_ENABLE_WIFI, data, reply, option); if (error != ERR_NONE) { WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d", WIFI_SVR_CMD_ENABLE_WIFI, error); return WIFI_OPT_FAILED; } int exception = reply.ReadInt32(); if (exception) { return WIFI_OPT_FAILED; } return ErrCode(reply.ReadInt32()); } // 处理请求 int WifiDeviceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { if (data.ReadInterfaceToken() != GetDescriptor()) { WIFI_LOGE("Sta stub token verification error"); return WIFI_OPT_FAILED; } int exception = data.ReadInt32(); if (exception) { return WIFI_OPT_FAILED; } HandleFuncMap::iterator iter = handleFuncMap.find(code); if (iter == handleFuncMap.end()) { WIFI_LOGI("not find function to deal, code %{public}u", code); reply.WriteInt32(0); reply.WriteInt32(WIFI_OPT_NOT_SUPPORTED); } else { (this->*(iter->second))(code, data, reply); } return 0; }
基本上自己有main函数入口:
xxxService继承IPCObjectStub 和 xxxInterface
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> newInstance = new xxxService();
int result = saMgr->AddSystemAbility(xxxSaId, newInstance);
本身没有main函数入口,需要借助safwk的main入口:
xxxService继承IPCObjectStub,xxxInterface 和 SystemAbility
// 注册方式2的第一种方式 REGISTER_SYSTEM_ABILITY_BY_ID(xxxService, xxxSaId, true); // 添加ability信息 Publish(this); // 在重写的OnStart函数中调用,注册到samgr中 // 注册方式2的第二种方式 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(WifiDeviceServiceImpl::GetInstance().GetRefPtr()); Publish(this) // WifiDeviceService 注册 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(WifiDeviceServiceImpl::GetInstance().GetRefPtr()); WifiDeviceServiceImpl::WifiDeviceServiceImpl() #ifdef OHOS_ARCH_LITE : mPublishFlag(false), mState(ServiceRunningState::STATE_NOT_START) #else : SystemAbility(WIFI_DEVICE_ABILITY_ID, true), mPublishFlag(false), mState(ServiceRunningState::STATE_NOT_START) #endif {}
xxxServiceProxy继承PeerHolder 和 xxxInterface
客户端类中定义一个静态变量:
// 定义静态变量,才能通过iface_cast创建一个包含IPCObjectProxy的xxxServiceProxy对象
static inline BrokerDelegator<xxxServiceProxy> delegator_;
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> object = saMgr->GetSystemAbility(SaId);
client = iface_cast<xxxInterface >(object);
// WIFI Device范例
std::unique_ptr<OHOS::Wifi::WifiDevice> wifiDevicePtr = OHOS::Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
bool WifiDeviceImpl::Init()
{
sptr<ISystemAbilityManager> sa_mgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> object = sa_mgr->GetSystemAbility(systemAbilityId_);
client_ = iface_cast<IWifiDevice>(object);
// ...
}
// 服务id配置 distributedschedule\samgr\interfaces\innerkits\samgr_proxy\include\system_ability_definition.h enum { // ... WIFI_DEVICE_SYS_ABILITY_ID = 1120, WIFI_HOTSPOT_SYS_ABILITY_ID = 1121, WIFI_ENHANCER_SYS_ABILITY_ID = 1122, WIFI_P2P_SYS_ABILITY_ID = 1123, // ... } static const std::map<int, std::string> saNameMap_ = { { 200, "AccountMgr" }, { 301, "AIEngine" }, { BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, "BundleMgr" }, { FORM_MGR_SERVICE_ID, "FormMgr" }, { WIFI_DEVICE_SYS_ABILITY_ID, "WifiDevice" }, { WIFI_HOTSPOT_SYS_ABILITY_ID, "WifiHotspot" }, { WIFI_ENHANCER_SYS_ABILITY_ID, "WifiEnhancer" }, { WIFI_P2P_SYS_ABILITY_ID, "WifiP2p" }, // ... }
Linux Socket编程(不限Linux) - 吴秦 - 博客园 (cnblogs.com)
使用一个.sock为后缀的文件来进行进程间通信,写入就是发送请求,读取就是接受该请求的返回信息.
wifi/wifi/services/wifi_standard/wifi_hal/main.c int main(void) { LOGI("Wifi hal service starting..."); char rpcSockPath[] = "/data/misc/wifi/unix_sock.sock"; if (access(rpcSockPath, 0) == 0) { unlink(rpcSockPath); } if (InitRpcFunc() < 0) { // 一、初始化函数表 LOGE("Init Rpc Function failed!"); return -1; } RpcServer *server = CreateRpcServer(rpcSockPath); // 二、建立Socket通信 if (server == NULL) { LOGE("Create RPC Server by %{public}s failed!", rpcSockPath); return -1; } SetRpcServerInited(server); setvbuf(stdout, NULL, _IOLBF, 0); signal(SIGINT, SignalExit); signal(SIGTERM, SignalExit); signal(SIGPIPE, SIG_IGN); SendStartNotify(); RunRpcLoop(server); // 三、进入事件循环 /* stop wpa_supplicant, hostapd, and other resources */ ForceStop(); for (int id = 0; id < AP_MAX_INSTANCE; id++) { StopSoftAp(id); } P2pForceStop(); ReleaseWifiHalVendorInterface(); /* clear RPC Server */ SetRpcServerInited(NULL); ReleaseRpcServer(server); ReleaseRpcFunc(); LOGI("hal service exists!"); return 0; } 二、建立Socket通信 RpcServer *CreateRpcServer(const char *path) { RpcServer *server = (RpcServer *)calloc(1, sizeof(RpcServer)); int flag = 1; do { int ret = CreateUnixServer(path, DEFAULT_LISTEN_QUEUE_SIZE); // CreateUnixServer,建立socket通信 server->listenFd = ret; server->loop = CreateEventLoop(MAX_SUPPORT_CLIENT_FD_SIZE); // 创建loop监听事件 // ... } while (0); if (flag) { ReleaseRpcServer(server); return NULL; } return server; } int CreateUnixServer(const char *path, int backlog) { struct sockaddr_un sockAddr; if (memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr)) != EOK) { return -1; } sockAddr.sun_family = AF_LOCAL; if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) { return -1; } int sock = CreateSocket(AF_LOCAL); // 创建socket int sock = socket(domain, SOCK_STREAM, 0); if (sock < 0) { return -1; } int keepAlive = 1; setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)); int reuseaddr = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, sizeof(reuseaddr)); // 绑定"/data/misc/wifi/unix_sock.sock"并进行监听 1.bind 2. listen if (bind(sock, (struct sockaddr *)&, sizeof(sockAddr)) < 0) { } if (SetNonBlock(sock, 1) != 0) { } fcntl(sock, F_SETFD, FD_CLOEXEC); if (listen(sock, backlog) < 0) { } return sock; } 三、进行事件循环 int RunRpcLoop(RpcServer *server) { if (server == NULL) { return -1; } EventLoop *loop = server->loop; while (!loop->stop) { BeforeLoop(server); int retval = epoll_wait(loop->epfd, loop->epEvents, loop->setSize, 5); // wait 5ms for (int i = 0; i < retval; ++i) { struct epoll_event *e = loop->epEvents + i; int fd = e->data.fd; unsigned int mask = CheckEventMask(e); if (fd == server->listenFd) { OnAccept(server, mask); // 接收事件: int fd = accept(server->listenFd, NULL, NULL); } else { DealFdEvents(server, fd, mask); } } } return 0; }
总结:
1.int socket(int domain, int type, int protocol); 创建socket
2.int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 绑定
3.int listen(int sockfd, int backlog); 监听
4.int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 接收请求
int WifiIdlClient::InitClient(void) { const std::string idlSockPath = "/data/misc/wifi/unix_sock.sock"; // .sock文件 pRpcClient = CreateRpcClient(idlSockPath.c_str()); // call CreateRpcClient // ... } RpcClient *CreateRpcClient(const char *path) { int fd = ConnectUnixServer(path); // 连接socket SetNonBlock(fd, 1); RpcClient *client = (RpcClient *)calloc(1, sizeof(RpcClient)); // ... client->context = CreateContext(CONTEXT_BUFFER_MIN_SIZE); // ... int ret = pthread_create(&client->threadId, NULL, RpcClientThreadDeal, client); // ... signal(SIGPIPE, SIG_IGN); return client; } int ConnectUnixServer(const char *path) { // ... sockAddr.sun_family = AF_LOCAL; if (strncpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), path, strlen(path)) != EOK) { return -1; } // 1.创建socket int sock = CreateSocket(AF_LOCAL); // int sock = socket(domain, SOCK_STREAM, 0); if (sock < 0) { return -1; } // 2.链接socket if (connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) { LOGE("connect failed!"); close(sock); return -1; } return sock; }
WifiErrorNo Start(void) { RpcClient *client = GetStaRpcClient(); LockRpcClient(client); Context *context = client->context; WriteBegin(context, 0); WriteFunc(context, "Start"); // 写入context->szWrite WriteEnd(context); if (RpcClientCall(client, "Start") != WIFI_IDL_OPT_OK) { // 发送事件到Server return WIFI_IDL_OPT_FAILED; } int result = WIFI_IDL_OPT_FAILED; ReadInt(context, &result); ReadClientEnd(client); UnlockRpcClient(client); return result; } int RemoteCall(RpcClient *client) { // ... Context *context = client->context; while (context->wBegin != context->wEnd && ret >= 0) { ret = ContextWriteNet(context); } if (ret < 0) { return ret; } ret = 0; /* reset ret value */ pthread_mutex_lock(&client->mutex); while (client->waitReply != CLIENT_STATE_DEAL_REPLY && client->waitReply != CLIENT_STATE_EXIT) { pthread_cond_wait(&client->condW, &client->mutex); } if (client->waitReply == CLIENT_STATE_EXIT) { ret = -1; } pthread_mutex_unlock(&client->mutex); return ret; } int ContextWriteNet(Context *context) { if (context->wBegin < context->wEnd) { int ret = MyWrite(context->fd, context->szWrite + context->wBegin, context->wEnd - context->wBegin);// 写入事件int ret = write(fd, buf + pos, count); if (ret > 0) { context->wBegin += ret; } return ret; } // ... return ret; }
int RpcStart(RpcServer *server, Context *context)
{
if (server == NULL || context == NULL) {
return HAL_FAILURE;
}
WifiErrorNo err = Start();
WriteBegin(context, 0);
WriteInt(context, err);
WriteEnd(context);
return HAL_SUCCESS;
}
// socket error
LOGE("%s: error on socket(): %d = %s", __func__, errno, strerror(errno));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。