OCap usage example

August 2, 2023

ID libkos_handles_simple_scenario

This article describes an OCap usage scenario in which the server program provides the following methods for accessing its resources:

  • OpenResource() – opens access to the resource.
  • UseResource() – uses the resource.
  • CloseResource() – closes access to the resource.

The client program uses these methods.

IDL description of interface methods:

package SimpleOCap

interface {

OpenResource(in UInt32 ID, out Handle handle);

UseResource(in Handle handle, in UInt8 param, out UInt8 result);

CloseResource(in Handle handle);

}

The scenario includes the following steps:

  1. The resource provider creates the user resource context and calls the KnHandleCreateUserObject() function to create the resource handle. The resource provider saves the resource handle in the user resource context.
  2. The client calls the OpenResource() method to open access to the resource.
    1. The resource provider creates the resource transfer context and calls the KnHandleCreateBadge() function to create a resource transfer context object and configure the notification receiver to receive notifications regarding the closure or termination of the resource transfer context object. The resource provider saves the handle of the resource transfer context object and the pointer to the user resource context in the resource transfer context.
    2. The resource provider uses the nk_handle_desc() macro to package the resource handle, permissions mask of the handle, and pointer to the resource transfer context object into the handle transport container.
    3. The handle is transferred from the resource provider to the client, which means that the client receives a descendant of the handle owned by the resource provider.
    4. The OpenResource() method call completes successfully. The client extracts the handle and permissions mask of the handle from the handle transport container by using the nk_get_handle() and nk_get_rights() functions, respectively. The handle permissions mask is not required by the client to query the resource, but is transferred so that the client can find out its permissions for accessing the resource.
  3. The client calls the UseResource() method to utilize the resource.
    1. The handle that was received from the resource provider at step 2 is used as an argument of the UseResource() method. Before calling this method, the client uses the nk_handle_desc() macro to package the handle into the handle transport container.
    2. The handle is dereferenced, after which the resource provider receives the pointer to the resource transfer context.
    3. The resource provider uses the nk_is_handle_dereferenced() function to verify that the dereferencing operation was completed instead of a handle transfer.
    4. The resource provider verifies that the access rights of the dereferenced handle (that was sent by the client) allows the requested operation with the resource, and extracts the pointer to the resource transfer context from the handle transport container. To do so, the resource provider uses the nk_get_badge_op() function, which extracts the pointer to the resource transfer context from the handle transport container if the received permissions mask has the corresponding flags set for the requested operation.
    5. The resource provider uses the resource transfer context and the user resource context to perform the corresponding operation with the resource as requested by the client. Then the resource provider sends the client the results of this operation.
    6. The UseResource() method call completes successfully. The client receives the results of the operation performed on the resource.
  4. The client calls the CloseResource() method to close access to the resource.
    1. The handle that was received from the resource provider at step 2 is used as an argument of the CloseResource() method. Before calling this method, the client uses the nk_handle_desc() macro to package the handle into the handle transport container. After the CloseResource() method is called, the client uses the KnHandleClose() function to delete the handle.
    2. The handle is dereferenced, after which the resource provider receives the pointer to the resource transfer context.
    3. The resource provider uses the nk_is_handle_dereferenced() function to verify that the dereferencing operation was completed instead of a handle transfer.
    4. The resource provider uses the nk_get_badge() function to extract the pointer to the resource transfer context from the handle transport container.
    5. The resource provider uses the KnHandleRevokeSubtree() function to revoke the handle owned by the client. The resource handle owned by the resource provider and the handle of the resource transfer context object are used as arguments of this function. The resource provider obtains access to these handles through the pointer to the resource transfer context. (Technically, the handle owned by the client does not have to be revoked because the client already deleted it. However, the revoke operation is performed in case the resource provider is not sure if the client actually deleted the handle).
    6. The CloseResource() method call completes successfully.
  5. The resource provider frees up the memory that was allocated for the resource transfer context and the user resource context.
    1. The resource provider calls the KnNoticeGetEvent() function to receive a notification that the resource transfer context object was closed, and uses the KnHandleClose() function to delete the handle of the resource transfer context object.
    2. The resource provider calls the KnNoticeGetEvent() function to receive a notification that the resource transfer context object has been terminated, and frees up the memory that was allocated for the resource transfer context.
    3. The resource provider uses the KnHandleClose() function to delete the resource handle and to free up the memory that was allocated for the user resource context.

Did you find this article helpful?
What can we do better?
Thank you for your feedback! You're helping us improve.
Thank you for your feedback! You're helping us improve.