bool ipc_client::ipc_connect(void) { struct sockaddr_un remote; int len; if (sfd != -1) return true; if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { supla_log(LOG_ERR, "Socket error %i", errno); return false; } remote.sun_family = AF_UNIX; snprintf(remote.sun_path, sizeof(remote.sun_path), "%s", scfg_string(CFG_IPC_SOCKET_PATH)); len = strnlen(remote.sun_path, 107) + sizeof(remote.sun_family); if (connect(sfd, (struct sockaddr *)&remote, len) == -1) { supla_log(LOG_ERR, "IPC connect error %i", errno); ipc_disconnect(); return false; } if (read() && strcmp(buffer, hello) == 0) return true; ipc_disconnect(); return false; }
static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond, gpointer user_data) { struct ipc *ipc = user_data; DBG(""); if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { error("IPC: command socket connect failed"); ipc_disconnect(ipc, false); return FALSE; } if (ipc->notifications) { ipc->notif_io = ipc_connect(ipc->path, ipc->size, notif_connect_cb, ipc); if (!ipc->notif_io) ipc_disconnect(ipc, false); return FALSE; } cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc); info("IPC: successfully connected (without notifications)"); return FALSE; }
static void msg_send_or_queue (void *conn, const struct iovec *iov, unsigned int iov_len) { struct conn_info *conn_info = (struct conn_info *)conn; unsigned int bytes_left; unsigned int bytes_msg = 0; int i; struct outq_item *outq_item; char *write_buf = 0; /* * Exit transmission if the connection is dead */ if (ipc_thread_active (conn) == 0) { return; } bytes_left = shared_mem_dispatch_bytes_left (conn_info); for (i = 0; i < iov_len; i++) { bytes_msg += iov[i].iov_len; } if (bytes_left < bytes_msg || list_empty (&conn_info->outq_head) == 0) { if (flow_control_state_set (conn_info, 1)) { flow_control_stats_update(conn_info->stats_handle, 1); } outq_item = api->malloc (sizeof (struct outq_item)); if (outq_item == NULL) { ipc_disconnect (conn); return; } outq_item->msg = api->malloc (bytes_msg); if (outq_item->msg == 0) { api->free (outq_item); ipc_disconnect (conn); return; } write_buf = outq_item->msg; for (i = 0; i < iov_len; i++) { memcpy (write_buf, iov[i].iov_base, iov[i].iov_len); write_buf += iov[i].iov_len; } outq_item->mlen = bytes_msg; list_init (&outq_item->list); pthread_mutex_lock (&conn_info->mutex); list_add_tail (&outq_item->list, &conn_info->outq_head); pthread_mutex_unlock (&conn_info->mutex); api->stats_increment_value (conn_info->stats_handle, "queue_size"); return; } msg_send (conn, iov, iov_len, MSG_SEND_LOCKED); api->stats_increment_value (conn_info->stats_handle, "dispatched"); }
void ipc_cleanup(struct ipc *ipc) { ipc_disconnect(ipc, true); g_free(ipc->services); g_free(ipc); }
int main(int argc, char* argv[]) { int rc; /* drop privileges */ if (drop_privs() < 0) return EXIT_FAILURE; /* parse arguments */ parse_args(argc, argv); /* initialize secure storage directory */ rc = storage_init(ss_data_root); if (rc < 0) return EXIT_FAILURE; /* open rpmb device */ rc = rpmb_open(rpmb_devname, dev_type); if (rc < 0) return EXIT_FAILURE; /* connect to Trusty secure storage server */ rc = ipc_connect(trusty_devname, ss_srv_name); if (rc < 0) return EXIT_FAILURE; /* enter main loop */ rc = proxy_loop(); ALOGE("exiting proxy loop with status (%d)\n", rc); ipc_disconnect(); rpmb_close(); return (rc < 0) ? EXIT_FAILURE : EXIT_SUCCESS; }
void __disconnect() { if (ipc_disconnect(__get_id(), SRV_ID) == OK) { printf("Clt: diconnected from srv\n"); } else { printf("Clt: could not disconnect from srv [ERROR]\n"); } }
static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond, gpointer user_data) { struct ipc *ipc = user_data; info("IPC: notification socket closed"); ipc->notif_watch = 0; ipc_disconnect(ipc, false); return FALSE; }
// Event Worker Thread // Processes ESIF Events void *esif_event_worker_thread(void *ptr) { int rc = 0; fd_set rfds = {0}; struct timeval tv = {0}; UNREFERENCED_PARAMETER(ptr); ESIF_TRACE_ENTRY_INFO(); CMD_OUT("Start ESIF Event Thread\n"); // Connect To Kernel IPC with infinite timeout ipc_autoconnect(0); // Run Until Told To Quit while (!g_quit) { #ifdef ESIF_FEAT_OPT_ACTION_SYSFS esif_ccb_sleep_msec(250); #else if (g_ipc_handle == ESIF_INVALID_HANDLE) { break; } if (rc > 0) { EsifEvent_GetAndSignalIpcEvent(); } FD_ZERO(&rfds); FD_SET((esif_ccb_socket_t)g_ipc_handle, &rfds); tv.tv_sec = 0; tv.tv_usec = 50000; /* 50 msec */ #ifdef ESIF_ATTR_OS_LINUX rc = select(g_ipc_handle + 1, &rfds, NULL, NULL, &tv); #endif #ifdef ESIF_ATTR_OS_WINDOWS // Windows does not support select/poll so we simulate here esif_ccb_sleep_msec(50); rc = 1; #endif #endif } if (g_ipc_handle != ESIF_INVALID_HANDLE) { ipc_disconnect(); } ESIF_TRACE_EXIT_INFO(); return 0; }
// IPC Connect eEsifError ipc_connect() { eEsifError rc = ESIF_OK; int check_kernel_version = ESIF_TRUE; ESIF_TRACE_ENTRY_INFO(); // Exit if IPC already connected if (g_ipc_handle != ESIF_INVALID_HANDLE) { return ESIF_OK; } // Connect to LF g_ipc_handle = esif_ipc_connect((char *)SESSION_ID); if (g_ipc_handle == ESIF_INVALID_HANDLE) { ESIF_TRACE_WARN("ESIF LF is not available\n"); rc = ESIF_E_NO_LOWER_FRAMEWORK; } else { char *outbuf = esif_ccb_malloc(OUT_BUF_LEN); char *kern_str = (outbuf != NULL ? esif_cmd_info(outbuf) : NULL); ESIF_TRACE_DEBUG("ESIF IPC Kernel Device Opened\n"); if (NULL != kern_str) { // Extract just the Kernel LF Version from the result string extract_kernel_version(kern_str, OUT_BUF_LEN); // Bypass Kernel Version check for DEBUG builds #if defined(ESIF_ATTR_DEBUG) check_kernel_version = ESIF_FALSE; #endif // Validate Kernel LF version is compatible with UF version if (check_kernel_version == ESIF_FALSE || esif_ccb_strcmp(kern_str, ESIF_VERSION) == 0) { ESIF_TRACE_INFO("Kernel Version: %s\n", kern_str); esif_ccb_sprintf(sizeof(g_esif_kernel_version), g_esif_kernel_version, "%s", kern_str); } else { ESIF_TRACE_ERROR("ESIF_LF Version (%s) Incompatible with ESIF_UF Version (%s)\n", kern_str, ESIF_VERSION); ipc_disconnect(); rc = ESIF_E_NOT_SUPPORTED; } } esif_ccb_free(outbuf); } ESIF_TRACE_EXIT_INFO_W_STATUS(rc); return rc; }
int coroipcs_ipc_service_exit (unsigned int service) { struct list_head *list, *list_next; struct conn_info *conn_info; for (list = conn_info_list_head.next; list != &conn_info_list_head; list = list_next) { list_next = list->next; conn_info = list_entry (list, struct conn_info, list); if (conn_info->service != service || (conn_info->state != CONN_STATE_THREAD_ACTIVE && conn_info->state != CONN_STATE_THREAD_REQUEST_EXIT)) { continue; } ipc_disconnect (conn_info); api->poll_dispatch_destroy (conn_info->fd, NULL); while (conn_info_destroy (conn_info) != -1) ; /* * We will return to prevent token loss. Schedwrk will call us again. */ return (-1); } /* * No conn info left in active list. We will traverse thru exit list. If there is any * conn_info->service == service, we will wait to proper end -> return -1 */ for (list = conn_info_exit_list_head.next; list != &conn_info_exit_list_head; list = list->next) { conn_info = list_entry (list, struct conn_info, list); if (conn_info->service == service) { return (-1); } } return (0); }
void coroipcs_ipc_exit (void) { struct list_head *list; struct conn_info *conn_info; unsigned int res; for (list = conn_info_list_head.next; list != &conn_info_list_head; list = list->next) { conn_info = list_entry (list, struct conn_info, list); if (conn_info->state != CONN_STATE_THREAD_ACTIVE) continue; ipc_disconnect (conn_info); #if _POSIX_THREAD_PROCESS_SHARED > 0 sem_destroy (&conn_info->control_buffer->sem_request_or_flush_or_exit); sem_destroy (&conn_info->control_buffer->sem_request); sem_destroy (&conn_info->control_buffer->sem_response); sem_destroy (&conn_info->control_buffer->sem_dispatch); #else semctl (conn_info->control_buffer->semid, 0, IPC_RMID); #endif /* * Unmap memory segments */ res = munmap ((void *)conn_info->control_buffer, conn_info->control_size); res = munmap ((void *)conn_info->request_buffer, conn_info->request_size); res = munmap ((void *)conn_info->response_buffer, conn_info->response_size); res = circular_memory_unmap (conn_info->dispatch_buffer, conn_info->dispatch_size); } }
static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond, gpointer user_data) { struct ipc *ipc = user_data; char buf[IPC_MTU]; ssize_t ret; int fd, err; if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { info("IPC: command socket closed"); ipc->cmd_watch = 0; goto fail; } fd = g_io_channel_unix_get_fd(io); ret = read(fd, buf, sizeof(buf)); if (ret < 0) { error("IPC: command read failed (%s)", strerror(errno)); goto fail; } err = ipc_handle_msg(ipc->services, ipc->service_max, buf, ret); if (err < 0) { error("IPC: failed to handle message (%s)", strerror(-err)); goto fail; } return TRUE; fail: ipc_disconnect(ipc, false); return FALSE; }
ipc_client::~ipc_client() { ipc_disconnect(); }
int coroipcs_handler_dispatch ( int fd, int revent, void *context) { mar_req_setup_t *req_setup; struct conn_info *conn_info = (struct conn_info *)context; int res; char buf = 0; if (ipc_thread_exiting (conn_info)) { return conn_info_destroy (conn_info); } /* * If an error occurs, request exit */ if (revent & (POLLERR|POLLHUP)) { ipc_disconnect (conn_info); return (0); } /* * Read the header and process it */ if (conn_info->service == SOCKET_SERVICE_INIT && (revent & POLLIN)) { pthread_attr_t thread_attr; /* * Receive in a nonblocking fashion the request * IF security invalid, send ERR_SECURITY, otherwise * send OK */ res = req_setup_recv (conn_info); if (res != CS_OK && res != CS_ERR_LIBRARY) { req_setup_send (conn_info, res); } if (res != CS_OK) { return (0); } pthread_mutex_init (&conn_info->mutex, NULL); req_setup = (mar_req_setup_t *)conn_info->setup_msg; /* * Is the service registered ? * Has service init function ? */ if (api->service_available (req_setup->service) == 0 || api->init_fn_get (req_setup->service) == NULL) { req_setup_send (conn_info, CS_ERR_NOT_EXIST); ipc_disconnect (conn_info); return (0); } #if _POSIX_THREAD_PROCESS_SHARED < 1 conn_info->semkey = req_setup->semkey; #endif res = memory_map ( req_setup->control_file, req_setup->control_size, (void *)&conn_info->control_buffer); if (res == -1) { goto send_setup_response; } conn_info->control_size = req_setup->control_size; res = memory_map ( req_setup->request_file, req_setup->request_size, (void *)&conn_info->request_buffer); if (res == -1) { goto send_setup_response; } conn_info->request_size = req_setup->request_size; res = memory_map ( req_setup->response_file, req_setup->response_size, (void *)&conn_info->response_buffer); if (res == -1) { goto send_setup_response; } conn_info->response_size = req_setup->response_size; res = circular_memory_map ( req_setup->dispatch_file, req_setup->dispatch_size, (void *)&conn_info->dispatch_buffer); if (res == -1) { goto send_setup_response; } conn_info->dispatch_size = req_setup->dispatch_size; send_setup_response: if (res == 0) { req_setup_send (conn_info, CS_OK); } else { req_setup_send (conn_info, CS_ERR_LIBRARY); ipc_disconnect (conn_info); return (0); } conn_info->service = req_setup->service; conn_info->refcount = 0; conn_info->setup_bytes_read = 0; #if _POSIX_THREAD_PROCESS_SHARED < 1 conn_info->control_buffer->semid = semget (conn_info->semkey, 3, 0600); #endif conn_info->pending_semops = 0; /* * ipc thread is the only reference at startup */ conn_info->refcount = 1; conn_info->state = CONN_STATE_THREAD_ACTIVE; conn_info->private_data = api->malloc (api->private_data_size_get (conn_info->service)); memset (conn_info->private_data, 0, api->private_data_size_get (conn_info->service)); api->init_fn_get (conn_info->service) (conn_info); /* create stats objects */ coroipcs_init_conn_stats (conn_info); pthread_attr_init (&thread_attr); /* * IA64 needs more stack space then other arches */ #if defined(__ia64__) pthread_attr_setstacksize (&thread_attr, 400000); #else pthread_attr_setstacksize (&thread_attr, 200000); #endif pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_JOINABLE); res = pthread_create (&conn_info->thread, &thread_attr, pthread_ipc_consumer, conn_info); pthread_attr_destroy (&thread_attr); /* * Security check - disallow multiple configurations of * the ipc connection */ if (conn_info->service == SOCKET_SERVICE_INIT) { conn_info->service = SOCKET_SERVICE_SECURITY_VIOLATION; } } else if (revent & POLLIN) { coroipcs_refcount_inc (conn_info); res = recv (fd, &buf, 1, MSG_NOSIGNAL); if (res == 1) { switch (buf) { case MESSAGE_REQ_CHANGE_EUID: if (priv_change (conn_info) == -1) { ipc_disconnect (conn_info); } break; default: res = 0; break; } } #if defined(COROSYNC_SOLARIS) || defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN) /* On many OS poll never return POLLHUP or POLLERR. * EOF is detected when recvmsg return 0. */ if (res == 0) { ipc_disconnect (conn_info); coroipcs_refcount_dec (conn_info); return (0); } #endif coroipcs_refcount_dec (conn_info); } if (revent & POLLOUT) { int psop = conn_info->pending_semops; int i; assert (psop != 0); for (i = 0; i < psop; i++) { res = send (conn_info->fd, &buf, 1, MSG_NOSIGNAL); if (res != 1) { return (0); } else { conn_info->pending_semops -= 1; } } if (conn_info->poll_state == POLL_STATE_INOUT) { conn_info->poll_state = POLL_STATE_IN; api->poll_dispatch_modify (conn_info->fd, POLLIN|POLLNVAL); } } return (0); }
/** * @brief * This function is executed at normal process termination. * * @par Description: * This function is called at normal process termination. * * @return * void */ static CsrBool signalCommon(void) { int i; /* --------------------------------------- */ /* Make sure signalCommon() only runs once */ /* --------------------------------------- */ static CsrBool signalCommonCalled = FALSE; if (signalCommonCalled == TRUE) { return FALSE; } signalCommonCalled = TRUE; /* --------------------------------------- */ #ifdef OSA_MEMORY_PROFILE stack_profile_report(); #endif /* Disable trace as it uses the OSA */ sme_trace_set_all_levels(TR_LVL_OFF); #ifdef IPC_IP ipc_disconnect(getMainData(linuxContext)->ipIpcCon); getMainData(linuxContext)->ipIpcCon = NULL; #ifdef CSR_AMP_ENABLE ipc_disconnect(getMainData(linuxContext)->ipHciIpcCon); getMainData(linuxContext)->ipHciIpcCon = NULL; ipc_disconnect(getMainData(linuxContext)->ipAclIpcCon); getMainData(linuxContext)->ipAclIpcCon = NULL; #endif #endif #ifdef IPC_CHARDEVICE ipc_disconnect(getMainData(linuxContext)->charIpcCon); getMainData(linuxContext)->charIpcCon = NULL; #endif if (linuxContext->fsmContext) { #ifdef CSR_AMP_ENABLE paldata_shutdown(linuxContext->palDataFsmContext); #endif #ifdef CSR_WIFI_NME_ENABLE csr_wifi_nme_shutdown(linuxContext->nmeFsmContext); #endif sme_shutdown(linuxContext->fsmContext); } for (i = 0; i < getMainData(linuxContext)->mibfiles.numElements; ++i) { CsrPfree(getMainData(linuxContext)->mibfiles.dataList[i].data); } CsrPfree(getMainData(linuxContext)->mibfiles.dataList); if (getMainData(linuxContext)->calibrationData.length) { CsrPfree(getMainData(linuxContext)->calibrationData.data); } return TRUE; }
static cs_error_t req_setup_recv ( struct conn_info *conn_info) { int res; struct msghdr msg_recv; struct iovec iov_recv; cs_error_t auth_res = CS_ERR_LIBRARY; #ifdef COROSYNC_LINUX struct cmsghdr *cmsg; char cmsg_cred[CMSG_SPACE (sizeof (struct ucred))]; int off = 0; int on = 1; struct ucred *cred; #endif msg_recv.msg_flags = 0; msg_recv.msg_iov = &iov_recv; msg_recv.msg_iovlen = 1; msg_recv.msg_name = 0; msg_recv.msg_namelen = 0; #ifdef COROSYNC_LINUX msg_recv.msg_control = (void *)cmsg_cred; msg_recv.msg_controllen = sizeof (cmsg_cred); #endif #ifdef COROSYNC_SOLARIS msg_recv.msg_accrights = 0; msg_recv.msg_accrightslen = 0; #endif /* COROSYNC_SOLARIS */ iov_recv.iov_base = &conn_info->setup_msg[conn_info->setup_bytes_read]; iov_recv.iov_len = sizeof (mar_req_setup_t) - conn_info->setup_bytes_read; #ifdef COROSYNC_LINUX setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)); #endif retry_recv: res = recvmsg (conn_info->fd, &msg_recv, MSG_NOSIGNAL); if (res == -1 && errno == EINTR) { api->stats_increment_value (conn_info->stats_handle, "recv_retry_count"); goto retry_recv; } else if (res == -1 && errno != EAGAIN) { return (CS_ERR_LIBRARY); } else if (res == 0) { #if defined(COROSYNC_SOLARIS) || defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN) /* On many OS poll never return POLLHUP or POLLERR. * EOF is detected when recvmsg return 0. */ ipc_disconnect (conn_info); return (CS_ERR_LIBRARY); #else return (CS_ERR_SECURITY); #endif } conn_info->setup_bytes_read += res; /* * currently support getpeerucred, getpeereid, and SO_PASSCRED credential * retrieval mechanisms for various Platforms */ #ifdef HAVE_GETPEERUCRED /* * Solaris and some BSD systems */ { ucred_t *uc = NULL; uid_t euid = -1; gid_t egid = -1; if (getpeerucred (conn_info->fd, &uc) == 0) { euid = ucred_geteuid (uc); egid = ucred_getegid (uc); conn_info->client_pid = ucred_getpid (uc); if (api->security_valid (euid, egid)) { auth_res = CS_OK; } else { auth_res = hdb_error_to_cs(errno); } ucred_free(uc); } } #elif HAVE_GETPEEREID /* * Usually MacOSX systems */ { uid_t euid; gid_t egid; /* * TODO get the peer's pid. * conn_info->client_pid = ?; */ euid = -1; egid = -1; if (getpeereid (conn_info->fd, &euid, &egid) == 0) { if (api->security_valid (euid, egid)) { auth_res = CS_OK; } else { auth_res = hdb_error_to_cs(errno); } } } #elif SO_PASSCRED /* * Usually Linux systems */ cmsg = CMSG_FIRSTHDR (&msg_recv); assert (cmsg); cred = (struct ucred *)CMSG_DATA (cmsg); if (cred) { conn_info->client_pid = cred->pid; if (api->security_valid (cred->uid, cred->gid)) { auth_res = CS_OK; } else { auth_res = hdb_error_to_cs(errno); } } #else /* no credentials */ auth_res = CS_OK; log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC authentication. Using no authentication\n"); #endif /* no credentials */ if (auth_res != CS_OK) { ipc_disconnect (conn_info); if (auth_res == CS_ERR_NO_RESOURCES) { log_printf (LOGSYS_LEVEL_ERROR, "Not enough file desciptors for IPC connection.\n"); } else { log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n"); } return auth_res; } if (conn_info->setup_bytes_read == sizeof (mar_req_setup_t)) { #ifdef COROSYNC_LINUX setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED, &off, sizeof (off)); #endif return (CS_OK); } return (CS_ERR_LIBRARY); }
static int process_frames(bdaddr_t address, unsigned long flags) { struct cmsghdr *cmsg; struct msghdr msg; struct iovec iv; struct hcidump_hdr *dh; struct btsnoop_pkt *dp; struct frame frm; struct pollfd fds[2]; int nfds = 0; char *buf, *ctrl; int len, hdr_size = HCIDUMP_HDR_SIZE; int polltimeout = -1; int sock = -1; int device = -1; if (snap_len < SNAP_LEN) snap_len = SNAP_LEN; if (flags & DUMP_BTSNOOP) hdr_size = BTSNOOP_PKT_SIZE; buf = malloc(snap_len + hdr_size); if (!buf) { perror("Can't allocate data buffer"); return -1; } dh = (void *) buf; dp = (void *) buf; frm.data = buf + hdr_size; ctrl = malloc(100); if (!ctrl) { free(buf); perror("Can't allocate control buffer"); return -1; } printf("snap_len: %d filter: 0x%lx\n", snap_len, parser.filter); memset(&msg, 0, sizeof(msg)); while (1) { nfds = 0; if (sock == -1) { device = hci_for_each_dev(0, find_device_by_address_callback, (long)&address); if (device != -1) { sock = open_socket(device, flags); if (sock != -1) { printf("hci%d Connected\n", device); (void)fflush(stdout); onBtConnect(); } } } if (sock != -1) { fds[nfds].fd = sock; fds[nfds].events = POLLIN; fds[nfds].revents = 0; nfds++; } /* ------------------------------------------------------------- */ /* Remote sme */ /* ------------------------------------------------------------- */ #ifdef IPC_IP // If we are not connected attempt to connect if (!smeConnection) { //printf("Sme Connect :: tcp:localhost:10101\n"); //(void)fflush(stdout); smeConnection = ipc_ip_connect("tcp:localhost:10101", NULL, NULL, NULL, NULL); if (smeConnection) { printf("Sme Connected\n"); (void)fflush(stdout); onIpcConnect(); } } if (smeConnection) { fds[nfds].fd = ipc_getFd(smeConnection); fds[nfds].events = POLLIN; fds[nfds].revents = 0; nfds++; } polltimeout = sock==-1?500:smeConnection?-1:500; #endif /* ------------------------------------------------------------- */ (void)fflush(stdout); int i, n = poll(fds, nfds, polltimeout); (void)fflush(stdout); if (n <= 0) continue; for (i = 0; i < nfds; i++) { if (fds[i].revents & (POLLHUP | POLLERR | POLLNVAL)) { if (fds[i].fd == sock) { printf("device: disconnected\n"); sock = -1; onBtDisconnect(); continue; } #ifdef IPC_IP else if (smeConnection && fds[i].fd == ipc_getFd(smeConnection)) { printf("Sme Disconnected\n"); (void)fflush(stdout); ipc_disconnect(smeConnection); smeConnection = NULL; continue; } #endif else { printf("client: disconnect\n"); } } } for (i = 0; i < nfds; i++) { #ifdef IPC_IP if (smeConnection && fds[i].fd == ipc_getFd(smeConnection) && fds[i].revents & (POLLIN | POLLPRI)) { CsrUint8* smeRxBuffer; CsrUint32 smeRxLength = 0; printf("Sme fd Triggered\n"); (void)fflush(stdout); if (ipc_message_recv(smeConnection, 0, &smeRxBuffer, &smeRxLength)) { if (smeRxLength != 0) { if (!remote_bt_signal_receive(NULL, smeRxBuffer, (CsrUint16)smeRxLength)) { printf("Sme unhandled ipc message\n"); (void)fflush(stdout); } ipc_message_free(smeConnection, smeRxBuffer); } continue; } /* Opps Disconnected */ printf("Sme Disconnected\n"); (void)fflush(stdout); ipc_disconnect(smeConnection); smeConnection = NULL; nfds--; onIpcDisconnect(); continue; } #endif if (sock != -1 && fds[i].fd == sock && fds[i].revents & (POLLIN | POLLPRI)) { iv.iov_base = frm.data; iv.iov_len = snap_len; msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = ctrl; msg.msg_controllen = 100; len = recvmsg(sock, &msg, MSG_DONTWAIT); if (len < 0) { if (errno == EAGAIN || errno == EINTR) continue; perror("Receive failed"); return -1; } /* Process control message */ frm.data_len = len; frm.dev_id = device; frm.in = 0; frm.pppdump_fd = parser.pppdump_fd; frm.audio_fd = parser.audio_fd; cmsg = CMSG_FIRSTHDR(&msg); while (cmsg) { switch (cmsg->cmsg_type) { case HCI_CMSG_DIR: frm.in = *((int *) CMSG_DATA(cmsg)); break; case HCI_CMSG_TSTAMP: frm.ts = *((struct timeval *) CMSG_DATA(cmsg)); break; } cmsg = CMSG_NXTHDR(&msg, cmsg); } frm.ptr = frm.data; frm.len = frm.data_len; /* Parse and print */ parse(&frm); } } } return 0; }
int main(int argc, char **argv) { int i = 0, client_id; char buf[200]; boolean failed = false; FILE * file; string messages[] = {"hello", "world!", NULL}; switch (fork()) { case -1: __fatal("Fork error"); break; case 0: /* child */ usleep(1000); client_id=getpid(); while ( messages[i]!=NULL && !failed ) { printf("\nEntro hijo\n"); ipc_connect(client_id, SRV_ID); printf("\nChild: about to send (\"%s\")\n", messages[i]); ipc_send(client_id, SRV_ID, messages[i], strlen(messages[i])); printf("Child: msg sent\n"); ipc_recv(client_id, buf, SRV_RESP_LEN); printf("Child: response received (%.*s)\n", SRV_RESP_LEN, buf); failed = !strneq(OK_MSG, buf, SRV_RESP_LEN); if (failed) { printf("Child: Error\n"); } else { printf("Child: ok response received\n"); } ipc_disconnect(client_id, SRV_ID); i++; } ipc_close(client_id); printf("Child: out %s\n",failed? "[ERROR]":"[OK]"); break; default: /* parent */ printf("\nPadre:\n"); printf("Server id in Test%d\n", getpid()); ipc_init(SRV_ID); printf("\nEntro padre\n"); while ( messages[i]!=NULL ) { ipc_connect(SRV_ID, INVALID); printf("Parent: about to read\n"); ipc_recv(SRV_ID, buf, strlen(messages[i])); // I can't omit this because usually the server receives the id at the beginning file=__open("client", "r", CLIENT_PATH); if(file==NULL){ printf("%s\n","Error opening client id file in parent"); } while(fscanf(file, "%d\n", &client_id) != EOF) {;} printf("Client id %d\n", client_id); printf("Parent: read (\"%.*s\") --(expecting: \"%s\")\n", (int)strlen(messages[i]), buf, messages[i]); if (strneq(messages[i], buf, strlen(messages[i]))) { printf("Parent: [OK]\n"); ipc_send(SRV_ID, client_id, OK_MSG, SRV_RESP_LEN); } else { printf("Parent: [ERROR]\n"); ipc_send(SRV_ID, client_id, NOT_OK_MSG, SRV_RESP_LEN); } ipc_disconnect(SRV_ID, INVALID); fclose(file); file = NULL; i++; } usleep(1000); ipc_close(SRV_ID); printf("Parent: out\n"); break; } return 0; }