예제 #1
0
//! Raw data based data exchange with the media_server
status_t
SendToPort(port_id sendPort, int32 msgCode, command_data* msg, size_t size)
{
	status_t status = write_port_etc(sendPort, msgCode, msg, size,
		B_RELATIVE_TIMEOUT, TIMEOUT);
	if (status != B_OK) {
		ERROR("SendToPort: write_port failed, msgcode 0x%lx, port %ld: %s\n",
			msgCode, sendPort, strerror(status));
		if (status == B_BAD_PORT_ID && sendPort == sMediaServerPort) {
			find_media_server_port();
			sendPort = sMediaServerPort;
		} else if (status == B_BAD_PORT_ID
			&& sendPort == sMediaAddonServerPort) {
			find_media_addon_server_port();
			sendPort = sMediaAddonServerPort;
		} else
			return status;

		status = write_port_etc(sendPort, msgCode, msg, size,
			B_RELATIVE_TIMEOUT, TIMEOUT);
		if (status != B_OK) {
			ERROR("SendToPort: retrying write_port failed, msgCode 0x%lx, "
				"port %ld: %s\n", msgCode, sendPort, strerror(status));
			return status;
		}
	}
	return B_OK;
}
예제 #2
0
// to be used only from a BView or BWindow
bool nsToolkit::CallMethodAsync(MethodInfo *info)
{
#ifdef DEBUG
	printf("CMA\n");
#endif
  ThreadInterfaceData id;

  GetInterface();

  id.data = info;
  id.waitingThread = 0;
	
  // Check message count to not exceed the port's capacity.
  // There seems to be a BeOS bug that allows more 
  // messages on a port than its capacity.
  port_info portinfo;
  if (get_port_info(eventport, &portinfo) != B_OK)
  {
    return false;
  }
  
  if (port_count(eventport) < portinfo.capacity - 20) 
  {
    if(write_port_etc(eventport, WM_CALLMETHOD, &id, sizeof(id), B_TIMEOUT, 0) == B_OK)
    {
      return true;
    }
  }
  return false;
}
예제 #3
0
// Synchronous version, not in use at the moment
bool nsToolkit::CallMethod(MethodInfo *info)
{
#ifdef DEBUG
  printf("TK-CM\n");
#endif
  ThreadInterfaceData id;

  GetInterface();

  id.data = info;
  id.waitingThread = find_thread(NULL);
  // Check message count to not exceed the port's capacity.
  // There seems to be a BeOS bug that allows more 
  // messages on a port than its capacity.
  port_info portinfo;
  if (get_port_info(eventport, &portinfo) != B_OK)
  {
    return false;
  }
  
  if (port_count(eventport) < portinfo.capacity - 20) 
  {
    // If we cannot write inside 5 seconds, something is really wrong.
    if(write_port_etc(eventport, WM_CALLMETHOD, &id, sizeof(id), B_TIMEOUT, 5000000) == B_OK)
    {
      // semantics for CallMethod are that it should be synchronous
   	  suspend_thread(id.waitingThread);
      return true;
    }
  }
  return false;
}
예제 #4
0
status_t
PostEvent(bluetooth_device* ndev, void* event, size_t size)
{
    struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
    status_t err;

    // Take actions on certain type of events.
    switch (outgoingEvent->ecode) {
    case HCI_EVENT_CONN_COMPLETE:
    {
        struct hci_ev_conn_complete* data
            = (struct hci_ev_conn_complete*)(outgoingEvent + 1);

        // TODO: XXX parse handle field
        HciConnection* conn = AddConnection(data->handle, BT_ACL,
                                            data->bdaddr, ndev->index);

        if (conn == NULL)
            panic("no mem for conn desc");
        conn->ndevice = ndev;
        TRACE("%s: Registered connection handle=%#x\n", __func__,
              data->handle);
        break;
    }

    case HCI_EVENT_DISCONNECTION_COMPLETE:
    {
        struct hci_ev_disconnection_complete_reply* data;

        data = (struct hci_ev_disconnection_complete_reply*)
               (outgoingEvent + 1);

        RemoveConnection(data->handle, ndev->index);
        TRACE("%s: unRegistered connection handle=%#x\n", __func__,
              data->handle);
        break;
    }

    }

    // forward to bluetooth server
    port_id port = find_port(BT_USERLAND_PORT_NAME);
    if (port != B_NAME_NOT_FOUND) {

        err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
                             event, size, B_TIMEOUT, 1 * 1000 * 1000);

        if (err != B_OK)
            ERROR("%s: Error posting userland %s\n", __func__, strerror(err));

    } else {
        ERROR("%s: bluetooth_server not found for posting!\n", __func__);
        err = B_NAME_NOT_FOUND;
    }

    return err;
}
예제 #5
0
void
BMediaEventLooper::SetEventLatency(bigtime_t latency)
{
	CALLED();
	// clamp to a valid value
	if (latency < 0)
		latency = 0;

	fEventLatency = latency;
	write_port_etc(ControlPort(), GENERAL_PURPOSE_WAKEUP, 0, 0, B_TIMEOUT, 0);
}
예제 #6
0
status_t
QueryPort(port_id requestPort, int32 msgCode, request_data* request,
	size_t requestSize, reply_data* reply, size_t replySize)
{
	status_t status = write_port_etc(requestPort, msgCode, request, requestSize,
		B_RELATIVE_TIMEOUT, TIMEOUT);
	if (status != B_OK) {
		ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld: %s\n",
			msgCode, requestPort, strerror(status));

		if (status == B_BAD_PORT_ID && requestPort == sMediaServerPort) {
			find_media_server_port();
			requestPort = sMediaServerPort;
		} else if (status == B_BAD_PORT_ID
			&& requestPort == sMediaAddonServerPort) {
			find_media_addon_server_port();
			requestPort = sMediaAddonServerPort;
		} else
			return status;

		status = write_port_etc(requestPort, msgCode, request, requestSize,
			B_RELATIVE_TIMEOUT, TIMEOUT);
		if (status != B_OK) {
			ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port "
				"%ld: %s\n", msgCode, requestPort, strerror(status));
			return status;
		}
	}

	int32 code;
	status = read_port_etc(request->reply_port, &code, reply, replySize,
		B_RELATIVE_TIMEOUT, TIMEOUT);
	if (status < B_OK) {
		ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld: %s\n",
			msgCode, request->reply_port, strerror(status));
	}

	return status < B_OK ? status : reply->result;
}
예제 #7
0
status_t
LinkSender::Flush(bigtime_t timeout, bool needsReply)
{
	if (fCurrentStatus < B_OK)
		return fCurrentStatus;

	EndMessage(needsReply);
	if (fCurrentStart == 0)
		return B_OK;

	STRACE(("info: LinkSender Flush() waiting to send messages of %ld bytes on port %ld.\n",
		fCurrentEnd, fPort));

	status_t err;
	if (timeout != B_INFINITE_TIMEOUT) {
		do {
			err = write_port_etc(fPort, kLinkCode, fBuffer,
				fCurrentEnd, B_RELATIVE_TIMEOUT, timeout);
		} while (err == B_INTERRUPTED);
	} else {
		do {
			err = write_port(fPort, kLinkCode, fBuffer, fCurrentEnd);
		} while (err == B_INTERRUPTED);
	}

	if (err < B_OK) {
		STRACE(("error info: LinkSender Flush() failed for %ld bytes (%s) on port %ld.\n",
			fCurrentEnd, strerror(err), fPort));
		return err;
	}

	STRACE(("info: LinkSender Flush() messages total of %ld bytes on port %ld.\n",
		fCurrentEnd, fPort));

	fCurrentEnd = 0;
	fCurrentStart = 0;

	return B_OK;
}
int
main()
{
	sSemaphore1 = create_sem(0L, "test semaphore 1");
	sSemaphore2 = create_sem(0L, "test semaphore 2");
	sPort1 = create_port(2L, "test port 1");
	sPort2 = create_port(1L, "test port 2");

	printf("semaphore 1: %ld\n", sSemaphore1);
	printf("semaphore 2: %ld\n", sSemaphore2);
	printf("port 1:      %ld\n", sPort1);
	printf("port 2:      %ld\n", sPort2);

	thread_id thread = spawn_thread(notifier_thread, "notifier",
		B_NORMAL_PRIORITY, NULL);
	resume_thread(thread);

	printf("thread:      %ld\n", thread);

	object_wait_info initialInfos[] = {
		{
			sSemaphore1,
			B_OBJECT_TYPE_SEMAPHORE,
			B_EVENT_ACQUIRE_SEMAPHORE
		},
		{
			sSemaphore2,
			B_OBJECT_TYPE_SEMAPHORE,
			B_EVENT_ACQUIRE_SEMAPHORE
		},
		{
			sPort1,
			B_OBJECT_TYPE_PORT,
			B_EVENT_READ
		},
		{
			sPort2,
			B_OBJECT_TYPE_PORT,
			B_EVENT_WRITE
		},
		{
			0,
			B_OBJECT_TYPE_FD,
			B_EVENT_READ
		},
		{
			thread,
			B_OBJECT_TYPE_THREAD,
			B_EVENT_INVALID
		}
	};
	int infoCount = sizeof(initialInfos) / sizeof(object_wait_info);

	while (true) {
		object_wait_info infos[infoCount];
		memcpy(infos, initialInfos, sizeof(initialInfos));

		ssize_t result = wait_for_objects_etc(infos, infoCount,
			B_RELATIVE_TIMEOUT, 10000000LL);

		if (result >= 0)
			printf("\nwait_for_objects(): %ld\n", result);
		else
			printf("\nwait_for_objects(): %s\n", strerror(result));

		print_events(infos, infoCount);

		for (int i = 0; i < infoCount; i++) {
			int32 type = infos[i].type;
			int32 object = infos[i].object;
			uint16 events = infos[i].events;
			char buffer[256];

			if (type == B_OBJECT_TYPE_SEMAPHORE) {
				if (events & B_EVENT_ACQUIRE_SEMAPHORE) {
					status_t error = acquire_sem_etc(object, 1,
						B_RELATIVE_TIMEOUT, 0);
					printf("acquire_sem(%ld): %s\n", object, strerror(error));
				}
			} else if (type == B_OBJECT_TYPE_PORT) {
				if (events & B_EVENT_READ) {
					int32 code;
					ssize_t bytesRead = read_port_etc(object, &code,
						buffer, sizeof(buffer), B_RELATIVE_TIMEOUT, 0);
					printf("read_port(%ld): %ld\n", object, bytesRead);
				}
				if (events & B_EVENT_WRITE) {
					status_t error = write_port_etc(object, 0xc0de, buffer, 10,
						B_RELATIVE_TIMEOUT, 0);
					printf("write_port(%ld): %s\n", object, strerror(error));
				}
			} else if (type == B_OBJECT_TYPE_FD) {
				if (events & B_EVENT_READ) {
					ssize_t bytesRead = read(object, buffer, sizeof(buffer));
					printf("read(%ld): %ld\n", object, bytesRead);
				}
			} else if (type == B_OBJECT_TYPE_THREAD) {
				if (events & B_EVENT_INVALID) {
					printf("thread %ld quit\n", object);
					infoCount--;
				}
			}
		}
	}

	return 0;
}
예제 #9
0
/*----------------------------------------------------------------------------*/
status_t
write_port(port_id port, int32 code, const void *buffer, size_t bufferSize)
{
	return write_port_etc(port, code, buffer, bufferSize, 0, 0);
}