Skip to content
Permalink
fmbt_work
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
943 lines (735 sloc) 33.3 KB
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
from os.path import (dirname, realpath)
from ctypes import (Structure, Union, POINTER, pointer, CFUNCTYPE,
cast, c_int, c_uint, c_char, c_char_p, c_void_p,
c_bool, c_double, CDLL, py_object)
# For basic Py2/Py3 compatibility
try:
mrp_range = xrange
except NameError:
mrp_range = range
# Murphy resource-native API related defines
(MRP_RES_CONNECTED, MRP_RES_DISCONNECTED) = (0, 1)
def conn_state_to_str(state):
"""
Returns the given Murphy connection status code as a string
:param state: Murphy connection status to be converted to a string
:return: String that represents the given connection status
* connected
* disconnected
* unknown
"""
return {
MRP_RES_CONNECTED: "connected",
MRP_RES_DISCONNECTED: "disconnected",
}.get(state, "unknown")
(MRP_RES_RESOURCE_LOST,
MRP_RES_RESOURCE_PENDING,
MRP_RES_RESOURCE_ACQUIRED,
MRP_RES_RESOURCE_AVAILABLE) = (0, 1, 2, 3)
def res_state_to_str(state):
"""
Returns the given Murphy resource state as a string
:param state: Murphy resource/resource set state to be converted to a string
:return: String that represents the given resource state
* acquired
* available
* lost
* pending
* unknown
"""
return {
MRP_RES_RESOURCE_ACQUIRED: "acquired",
MRP_RES_RESOURCE_AVAILABLE: "available",
MRP_RES_RESOURCE_LOST: "lost",
MRP_RES_RESOURCE_PENDING: "pending",
}.get(state, "unknown")
(MRP_RES_ERROR_NONE,
MRP_RES_ERROR_CONNECTION_LOST,
MRP_RES_ERROR_INTERNAL,
MRP_RES_ERROR_MALFORMED) = (0, 1, 2, 3)
def error_to_str(error):
"""
Returns the given Murphy connection error state as a string
:param error: Murphy connection error state to be converted to a string
:return: String that represents the given connection error state
* none
* connection lost
* internal
* malformed
* unknown
"""
return {
MRP_RES_ERROR_NONE: "none",
MRP_RES_ERROR_CONNECTION_LOST: "connection lost",
MRP_RES_ERROR_INTERNAL: "internal",
MRP_RES_ERROR_MALFORMED: "malformed",
}.get(error, "unknown")
mrp_common = None
mrp_reslib = None
mrp_in_tree = None
if os.environ.get("MRP_IN_TREE"):
mrp_in_tree = True
def load_murphy():
global mrp_common
global mrp_reslib
global mrp_in_tree
if not mrp_common or not mrp_reslib:
if mrp_in_tree:
# FIXME: This fails if run in an interpreter (since __file__ is not available)
path = dirname(realpath(__file__))
# Load the murphy resource API library as well as the common library
mrp_common = CDLL(path + "/../src/.libs/libmurphy-common.so")
mrp_reslib = CDLL(path + "/../src/.libs/libmurphy-resource.so")
else:
mrp_common = CDLL("libmurphy-common.so")
mrp_reslib = CDLL("libmurphy-resource.so")
load_murphy()
# Create general abstractions around the things we throw around
class MrpMainloop(Structure):
pass
class MrpResourceCtx(Structure):
_fields_ = [("state", c_uint),
("zone", c_char_p),
("priv", c_void_p)]
class MrpResourceSet(Structure):
_fields_ = [("application_class", c_char_p),
("state", c_uint),
("priv", c_void_p)]
class MrpStringArray(Structure):
_fields_ = [("num_strings", c_int),
("strings", POINTER(c_char_p))]
class MrpResource(Structure):
_fields_ = [("name", c_char_p),
("state", c_uint),
("priv", c_void_p)]
class MrpAttributeUnion(Union):
_fields_ = [("string", c_char_p),
("integer", c_int),
("unsignd", c_uint),
("floating", c_double)]
class MrpAttribute(Structure):
_anonymous_ = ("u")
_fields_ = [("name", c_char_p),
("type", c_char),
("u", MrpAttributeUnion)]
class UserData(Structure):
_fields_ = [("conn", py_object),
("opaque", py_object)]
# Set the arguments/return value types for used variables
mrp_common.mrp_mainloop_create.restype = POINTER(MrpMainloop)
mrp_reslib.mrp_res_create.restype = POINTER(MrpResourceCtx)
mrp_reslib.mrp_res_destroy.argtypes = [POINTER(MrpResourceCtx)]
mrp_reslib.mrp_res_destroy.restype = None
mrp_reslib.mrp_res_list_application_classes.argtypes = [POINTER(MrpResourceCtx)]
mrp_reslib.mrp_res_list_application_classes.restype = POINTER(MrpStringArray)
mrp_reslib.mrp_res_list_resources.argtypes = [POINTER(MrpResourceCtx)]
mrp_reslib.mrp_res_list_resources.restype = POINTER(MrpResourceSet)
mrp_reslib.mrp_res_create_resource_set.argtypes = [POINTER(MrpResourceCtx),
c_char_p, c_void_p,
c_void_p]
mrp_reslib.mrp_res_create_resource_set.restype = POINTER(MrpResourceSet)
mrp_reslib.mrp_res_set_autorelease.argtypes = [c_bool,
POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_set_autorelease.restype = c_bool
mrp_reslib.mrp_res_delete_resource_set.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_delete_resource_set.restype = None
mrp_reslib.mrp_res_copy_resource_set.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_copy_resource_set.restype = POINTER(MrpResourceSet)
mrp_reslib.mrp_res_equal_resource_set.argtypes = [POINTER(MrpResourceSet),
POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_equal_resource_set.restype = c_bool
mrp_reslib.mrp_res_acquire_resource_set.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_acquire_resource_set.restype = c_int
mrp_reslib.mrp_res_release_resource_set.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_release_resource_set.restype = c_int
mrp_reslib.mrp_res_get_resource_set_id.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_get_resource_set_id.restype = c_int
mrp_reslib.mrp_res_create_resource.argtypes = [POINTER(MrpResourceSet),
c_char_p, c_bool, c_bool]
mrp_reslib.mrp_res_create_resource.restype = POINTER(MrpResource)
mrp_reslib.mrp_res_list_resource_names.argtypes = [POINTER(MrpResourceSet)]
mrp_reslib.mrp_res_list_resource_names.restype = POINTER(MrpStringArray)
mrp_reslib.mrp_res_get_resource_by_name.argtypes = [POINTER(MrpResourceSet),
c_char_p]
mrp_reslib.mrp_res_get_resource_by_name.restype = POINTER(MrpResource)
mrp_reslib.mrp_res_delete_resource.argtypes = [POINTER(MrpResource)]
mrp_reslib.mrp_res_delete_resource.restype = None
mrp_reslib.mrp_res_delete_resource_by_name.argtypes = [POINTER(MrpResourceSet),
c_char_p]
mrp_reslib.mrp_res_delete_resource_by_name.restype = c_bool
mrp_reslib.mrp_res_list_attribute_names.argtypes = [POINTER(MrpResource)]
mrp_reslib.mrp_res_list_attribute_names.restype = POINTER(MrpStringArray)
mrp_reslib.mrp_res_get_attribute_by_name.argtypes = [POINTER(MrpResource),
c_char_p]
mrp_reslib.mrp_res_get_attribute_by_name.restype = POINTER(MrpAttribute)
mrp_reslib.mrp_res_set_attribute_string.argtypes = [POINTER(MrpAttribute),
c_char_p]
mrp_reslib.mrp_res_set_attribute_string.restype = c_int
mrp_reslib.mrp_res_set_attribute_uint.argtypes = [POINTER(MrpAttribute),
c_uint]
mrp_reslib.mrp_res_set_attribute_uint.restype = c_int
mrp_reslib.mrp_res_set_attribute_int.argtypes = [POINTER(MrpAttribute),
c_int]
mrp_reslib.mrp_res_set_attribute_int.restype = c_int
mrp_reslib.mrp_res_set_attribute_double.argtypes = [POINTER(MrpAttribute),
c_double]
mrp_reslib.mrp_res_set_attribute_double.restype = c_int
mrp_reslib.mrp_res_free_string_array.argtypes = [POINTER(MrpStringArray)]
mrp_reslib.mrp_res_free_string_array.restype = None
mrp_common.mrp_mainloop_destroy.restype = None
def map_attr_type_to_py_type(attr_type):
"""
Converts a Murphy attribute type to a Python basic type
:param attr_type: Character that represents a given attribute's type
:return: Python basic type that represents the type of a given attribute
"""
return {
"i": int,
"u": int,
"f": float,
"s": str,
}.get(attr_type)
class Attribute(object):
def __init__(self, res, name):
"""
Gets the according attribute out of a given resource. Usually called by a Resource object.
:param res: Resource the attribute belongs to
:param name: Name of the attribute to return
:return: Attribute object created according to the parameters
"""
self.res = res
self.attr = None
self.attr = \
mrp_reslib.mrp_res_get_attribute_by_name(pointer(res.res),
name).contents
if not self.attr:
raise MemoryError("An invalid attribute pointer was received")
def set_value_to(self, value):
"""
Sets the value of this attribute according to the parameter
:param value: Value to be set in this attribute
:return: Boolean that notes if the action was successful or not
"""
value_type = self.attr.type
ret_val = 1
if value_type == "\0":
return False
if not isinstance(value, map_attr_type_to_py_type(value_type)):
return False
if isinstance(value, int):
if value_type == "i":
ret_val = mrp_reslib.mrp_res_set_attribute_int(pointer(self.attr), value)
elif value_type == "u":
if value < 0:
return False
else:
ret_val = mrp_reslib.mrp_res_set_attribute_uint(pointer(self.attr), value)
else:
return False
elif isinstance(value, float):
ret_val = mrp_reslib.mrp_res_set_attribute_double(pointer(self.attr), value)
elif isinstance(value, str):
ret_val = mrp_reslib.mrp_res_set_attribute_string(pointer(self.attr), value)
else:
return False
return bool(not ret_val)
def get_type(self):
"""
Returns the type of this attribute as a single character
:return: Character that represents the type of this attribute.
* i (signed 32bit integer)
* u (unsigned 32bit integer)
* f (double floating point value)
* s (string)
"""
return self.attr.type
def get_value(self):
"""
Returns the value currently set to this attribute.
:return: Value currently set to this attribute
"""
attr_type = self.attr.type
if attr_type == "i":
return self.attr.integer
elif attr_type == "u":
return self.attr.unsignd
elif attr_type == "f":
return self.attr.floating
elif attr_type == "s":
return self.attr.string
else:
return None
def get_name(self):
"""
Returns the name of this attribute.
:return: Name of this attribute
"""
return self.attr.name
class Resource(object):
def __init__(self, res_set, name, mandatory=True, shared=False):
"""
Creates (adds) a resource to a specific resource set. Has a name, status as well as an arbitrary amount of
attributes. The names and attributes are set in the Murphy configuration, and cannot be modified
on the fly. Attributes' values are application-specific, so there is no callback related to modification of
those.
:param res_set: Resource set to which this resource will be added
:param name: Name of the resource to be added
:param mandatory: Optional boolean parameter that notes whether or not this resource is
mandatory for a given resource set to work correctly. If set to True (default), in case
this resource is not acquired, it will cause the acquisition process to fail instead
of letting the user acquire a partial set of resources.
:param shared: Optional boolean parameter that notes whether or not this resource can be shared
with other clients. By default set to False.
:return: Resource object created according to the parameters
"""
self.res_set = res_set
res = \
mrp_reslib.mrp_res_create_resource(res_set.res_set,
name, mandatory,
shared)
if not res:
raise MemoryError("An invalid resource pointer was received")
self.res = res.contents
def delete(self):
"""
Deletes (removes) this resource from a given resource set
:return: Void
"""
self.res_set.delete_resource(self)
def list_attribute_names(self):
"""
Creates a list of the names of available attributes in this resource
:return: List of the names of attributes in this resource
"""
attribute_list = []
mrp_list = \
mrp_reslib.mrp_res_list_attribute_names(pointer(self.res))
if mrp_list:
for i in mrp_range(mrp_list.contents.num_strings):
attribute_list.append(mrp_list.contents.strings[i])
mrp_reslib.mrp_res_free_string_array(mrp_list)
return attribute_list
def get_attribute_by_name(self, name):
"""
Returns an Attribute object of the attribute that carries the given name in this resource
:param name: Name of the attribute to return
:return: None in case of failure, an Attribute object in case of success
"""
attr = None
try:
attr = Attribute(self, name)
except:
return None
return attr
def get_state(self):
"""
Returns the state of this resource as a string
:return: String that represents the last updated state of this resource
* acquired
* available
* lost
* pending
* unknown
"""
return res_state_to_str(self.res.state)
def get_name(self):
"""
Returns the name of this resource as a string
:return: String that represents the name of this resource
"""
return self.res.name
class GivenResource(Resource):
def __init__(self, res_set, res):
"""
Creates a basic Resource object based on the parameters given
:param res_set: Resource set under which this resource will be added
:param res: Ctypes resource pointer pointed to the resource to be added
:return: GivenResource object created according to the parameters
"""
self.res_set = res_set
self.res = res.contents
class ResourceSet(object):
def __init__(self, res_cb, conn, mrp_class):
"""
Creates a resource set, which is the basic unit of acquiring and releasing resources. Resources can be
acquired or lost independently if the configuration permits, but the client can only request and release
whole resource sets. Usually used via Connection.create_resource_set() and not directly.
:param res_cb: Resource callback to be called when there is an update in this resource set
:param conn: Connection to which this ResourceSet belongs
:param mrp_class: Application class to which this resource set belongs
:return: ResourceSet object created according to the parameters
"""
self.conn = conn
self.res_cb = res_cb
# Create a python callback for resources
res_callbackfunc = CFUNCTYPE(None, POINTER(MrpResourceCtx),
POINTER(MrpResourceSet),
c_void_p)
def res_callback_func(res_ctx_p, res_set_p, userdata_p):
opaque = cast(userdata_p, POINTER(UserData)).contents.opaque
passed_conn = GivenConnection(res_ctx_p)
passed_res_set = GivenResourceSet(passed_conn, res_set_p)
# Call the actual higher-level python callback func
self.res_cb(passed_res_set, opaque)
self.res_callback = res_callbackfunc(res_callback_func)
res_set = \
mrp_reslib.mrp_res_create_resource_set(pointer(conn.res_ctx),
mrp_class,
self.res_callback,
pointer(conn.udata))
if not res_set:
raise MemoryError("An invalid resource set pointer was received")
self.res_set = res_set.contents
def acquire(self):
"""
Attempts to acquire the resources in this resource set. Success here only means that the call succeeded,
and actual changes to the resource set's status will only be visible within a related resource callback.
:return: Tuple of boolean and a string; The boolean is True when the order was successfully completed,
and False when not. The string represents one of the Murphy error states.
* none
* connection lost
* internal
* malformed
* unknown
"""
ret_val = \
mrp_reslib.mrp_res_acquire_resource_set(pointer(self.res_set))
if not ret_val:
return True, error_to_str(ret_val)
else:
return False, error_to_str(ret_val)
def release(self):
"""
Releases the resources in this resource set.
:return: Tuple of boolean and a string; The boolean is True when the order was successfully completed,
and False when not. The string represents one of the Murphy error states.
* none
* connection lost
* internal
* malformed
* unknown
"""
ret_val = \
mrp_reslib.mrp_res_release_resource_set(pointer(self.res_set))
if not ret_val:
return True, error_to_str(ret_val)
else:
return False, error_to_str(ret_val)
def get_id(self):
"""
Gets the numeric ID of this resource set.
:return: Numeric ID of this resource set
"""
return \
mrp_reslib.mrp_res_get_resource_set_id(pointer(self.res_set))
def create_resource(self, name, mandatory=True, shared=False):
"""
Creates (adds) a resource to this resource set. The mandatory and shared flags can only be set
during resource creation, so if they have to be set to specific values, they should be set here.
:param name: Name of the resource to add to this resource set
:param mandatory: Optional boolean parameter that notes whether or not this resource is
mandatory for this resource set to work correctly. If set to True (default), in case
this resource is not acquired, it will cause the acquisition process to fail instead
of letting the user acquire a partial set of resources.
:param shared: Optional boolean parameter that notes whether or not this resource can be shared
with other clients. By default set to False.
:return: Resource object created according to the parameters given
"""
return Resource(self, name, mandatory, shared)
def list_resource_names(self):
"""
Creates a list of the names of available resources in this resource set
:return: List of the names of resources in this resource set
"""
names = []
mrp_list = \
mrp_reslib.mrp_res_list_resource_names(pointer(self.res_set))
if mrp_list:
for i in mrp_range(mrp_list.contents.num_strings):
names.append(mrp_list.contents.strings[i])
mrp_reslib.mrp_res_free_string_array(mrp_list)
return names
def get_resource_by_name(self, name):
"""
Returns a Resource object of the resource that carries the given name in this resource set
:param name: Name of the resource to return
:return: None in case of failure, a GivenResource object in case of success
"""
resource = None
mrp_res = \
mrp_reslib.mrp_res_get_resource_by_name(pointer(self.res_set),
name)
if mrp_res:
resource = GivenResource(self, mrp_res)
return resource
@staticmethod
def delete_resource(res):
"""
Deletes (removes) a resource from this resource set.
:param res: Resource to be removed from this resource set
:return: Void
"""
mrp_reslib.mrp_res_delete_resource(pointer(res.res))
def delete_resource_by_name(self, name):
"""
Deletes (removes) a resource from this resource set that carries the given name
in this resource set.
:param name: Name of the resource to be removed from this resource set
:return: Boolean that notes if the action was successful or not
"""
return bool(mrp_reslib.mrp_res_delete_resource_by_name(pointer(self.res_set),
name))
def get_state(self):
"""
Returns the state of this resource set as a string
:return: String that represents the last updated state of this resource set
* acquired
* available
* lost
* pending
* unknown
"""
return res_state_to_str(self.res_set.state)
def equals(self, other):
"""
Checks if this resource set in general equals another given resource set
:param other: Other ResourceSet object against which to compare
:return: Boolean that notes if the resource sets were equal or not
"""
return bool(mrp_reslib.mrp_res_equal_resource_set(pointer(self.res_set),
pointer(other.res_set)))
def set_autorelease(self, status):
"""
Sets the automatic release flag for this resource set. If set to true, if this resource set is lost, it will
be automatically released instead of having Murphy re-acquire it for this client.
:param status: State to which to set this flag. By default False.
:return: Boolean that notes if the action was successful or not
"""
return bool(mrp_reslib.mrp_res_set_autorelease(status, pointer(self.res_set)))
def delete(self):
"""
Deletes this resource set.
:return: Void
"""
mrp_reslib.mrp_res_delete_resource_set(pointer(self.res_set))
self.res_set = None
def update(self, other):
"""
Updates the resource set with information from another resource set. Usually used in resource callbacks.
:param other: Other resource set from which the information will be copied from
:return: False in case of failure, True in case of success.
"""
mrp_res_set = \
mrp_reslib.mrp_res_copy_resource_set(pointer(other.res_set))
if mrp_res_set:
if self.res_set:
self.delete()
self.res_set = mrp_res_set.contents
return True
else:
return False
class ResourceListing(ResourceSet):
def __init__(self, conn):
"""
Creates a basic ResourceSet object that contains all of the resources available in the system.
:param conn: Connection to which this resource set is to be created to
:return: ResourceListing object with the parameters you have given
"""
self.conn = conn
res_set = \
mrp_reslib.mrp_res_list_resources(self.conn.res_ctx)
if not res_set:
raise MemoryError("An invalid resource set pointer was received")
self.res_set = res_set.contents
class GivenResourceSet(ResourceSet):
def __init__(self, conn, res_set):
"""
Creates a basic ResourceSet object based on the parameters given
:param conn: Connection object to which this object will be connected
:param res_set: Murphy ctypes resource set around which this object will be made
:return: ResourceListing object with the parameters you have given
"""
self.conn = conn
self.res_set = res_set.contents
class Connection(object):
def __init__(self, status_cb, opaque_data):
"""
Creates a new connection and sets the status callback as well as the opaque user data object.
The connect() function actually creates the mainloop and initiates the connection, and the
disconnect() function will disconnect and clean up.
:param status_cb: Function to call when a status callback is called. Will be called with three
parameters: the connection, the Murphy error state as a string as well as the opaque data
:param opaque_data: A python object that will be passed to the callbacks under this connection
"""
self.udata = UserData(self, opaque_data)
self.mainloop = None
self.res_ctx = None
self.status_cb = status_cb
self.conn_status_callback = None
self.conn_status_callback_called = False
self.connected_to_murphy = False
def conn_status_callback_func(res_ctx_p, orig_error_code, userdata_p):
self.conn_status_callback_called = True
conn = GivenConnection(res_ctx_p)
error_code = error_to_str(orig_error_code)
if error_code == "none" and conn.get_state() == "connected":
self.connected_to_murphy = True
opaque = cast(userdata_p, POINTER(UserData)).contents.opaque
# Call the actual Python-level callback func
self.status_cb(conn, error_code, opaque)
# Create the connection status callback
conn_status_callbackfunc = CFUNCTYPE(None, POINTER(MrpResourceCtx),
c_uint, c_void_p)
self.conn_status_callback = \
conn_status_callbackfunc(conn_status_callback_func)
def connect(self):
"""
Creates the Murphy mainloop and initiates the initial connection to Murphy
:return: Boolean that tells if you are connected or not
"""
mainloop = mrp_common.mrp_mainloop_create()
if not mainloop:
self.disconnect()
return False
self.mainloop = mainloop.contents
res_ctx = mrp_reslib.mrp_res_create(pointer(self.mainloop),
self.conn_status_callback,
pointer(self.udata))
if not res_ctx:
self.disconnect()
return False
self.res_ctx = res_ctx.contents
while self.iterate():
if not self.conn_status_callback_called:
continue
else:
connected = self.connected_to_murphy
if not connected:
self.disconnect()
return connected
def iterate(self):
"""
Iterates the full Murphy mainloop once, usually results in callbacks being called and status
updated.
:return: Boolean that notes if the action was successful or not
"""
if pointer(self.mainloop):
return bool(mrp_common.mrp_mainloop_iterate(pointer(self.mainloop)))
else:
return False
def run(self):
"""
Iterates the full Murphy mainloop until you disconnect.
:return: Boolean that notes if the action was successful or not
"""
if pointer(self.mainloop):
return bool(mrp_common.mrp_mainloop_run(pointer(self.mainloop)))
else:
return False
def disconnect(self):
"""
Disconnects from Murphy and destroys the mainloop, cleans up related things. Does not free resources or
resource sets and so forth. That has to be done separately.
:return: Void
"""
if self.res_ctx:
mrp_reslib.mrp_res_destroy(pointer(self.res_ctx))
self.res_ctx = None
if self.mainloop:
mrp_common.mrp_mainloop_quit(pointer(self.mainloop), 0)
mrp_common.mrp_mainloop_destroy(pointer(self.mainloop))
self.mainloop = None
self.reset_variables()
def reset_variables(self):
"""
Resets the connection-related class variables. Called from disconnect()
:return: Void
"""
self.conn_status_callback_called = False
self.connected_to_murphy = False
def create_resource_set(self, res_cb, mrp_class):
"""
Creates a new resource set to this connection
:param res_cb: Resource callback to be called when there is an update in the resource set.
The same callback can be used for multiple resource sets, in which case the
user must check which resource set is the one receiving an update within the
callback.
:param mrp_class: Application class to which this resource set belongs
:return: ResourceSet object created according to the parameters
"""
return ResourceSet(res_cb, self, mrp_class)
def list_application_classes(self):
"""
Creates a list of the names of available application classes
:return: List of the names of available application classes in the system
"""
class_list = []
mrp_list = \
mrp_reslib.mrp_res_list_application_classes(pointer(self.res_ctx))
if mrp_list:
for i in mrp_range(mrp_list.contents.num_strings):
class_list.append(mrp_list.contents.strings[i])
return class_list
def list_resources(self):
"""
Creates a resource set that contains all of the available resources
:return: Resource set containing all of the resources available in the system
"""
return ResourceListing(self)
def get_state(self):
"""
Returns the current connection state as a string
:return: String containing the current connection state
* connected
* disconnected
* unknown
"""
if not self.res_ctx:
return "disconnected"
else:
return conn_state_to_str(self.res_ctx.state)
def get_opaque_data(self):
"""
Returns the opaque user set data structure
:return: Object that was set as the opaque user set data when the connection was created
"""
return self.udata.opaque
class GivenConnection(Connection):
def __init__(self, res_ctx):
"""
Creates a basic Connection object that contains the resource context from an available resource context.
Generally used in cases where there is a need for a basic (not all functionality available) version of a
Connection object.
:param res_ctx: Resource context around which this object will be created
:return: GivenConnection object that is a limited version of the Connection object
"""
self.res_ctx = res_ctx.contents