예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: coroipcs.c 프로젝트: emrehe/corosync
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");
}
예제 #4
0
void ipc_cleanup(struct ipc *ipc)
{
	ipc_disconnect(ipc, true);

	g_free(ipc->services);
	g_free(ipc);
}
예제 #5
0
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;
}
예제 #6
0
파일: client.c 프로젝트: kpjjpk/so-tp1
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");
	}
}
예제 #7
0
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;
}
예제 #8
0
파일: esif_uf_event.c 프로젝트: hoangt/dptf
// 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;
}
예제 #9
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;
}
예제 #10
0
파일: coroipcs.c 프로젝트: emrehe/corosync
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);
}
예제 #11
0
파일: coroipcs.c 프로젝트: emrehe/corosync
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);
	}
}
예제 #12
0
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;
}
예제 #13
0
ipc_client::~ipc_client() { ipc_disconnect(); }
예제 #14
0
파일: coroipcs.c 프로젝트: emrehe/corosync
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);
}
예제 #15
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;
}
예제 #16
0
파일: coroipcs.c 프로젝트: emrehe/corosync
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);
}
예제 #17
0
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;
}
예제 #18
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;
}