# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function
from cryptography import utils
from cryptography.exceptions import (
InvalidSignature, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.openssl.utils import _truncate_digest
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import (
AsymmetricSignatureContext, AsymmetricVerificationContext, ec
)
def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):
"""
This function truncates digests that are longer than a given elliptic
curve key's length so they can be signed. Since elliptic curve keys are
much shorter than RSA keys many digests (e.g. SHA-512) may require
truncation.
"""
_lib = backend._lib
_ffi = backend._ffi
group = _lib.EC_KEY_get0_group(ec_key_cdata)
with backend._tmp_bn_ctx() as bn_ctx:
order = _lib.BN_CTX_get(bn_ctx)
backend.openssl_assert(order != _ffi.NULL)
res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
backend.openssl_assert(res == 1)
order_bits = _lib.BN_num_bits(order)
return _truncate_digest(digest, order_bits)
def _ec_key_curve_sn(backend, ec_key):
group = backend._lib.EC_KEY_get0_group(ec_key)
backend.openssl_assert(group != backend._ffi.NULL)
nid = backend._lib.EC_GROUP_get_curve_name(group)
# The following check is to find EC keys with unnamed curves and raise
# an error for now.
if nid == backend._lib.NID_undef:
raise NotImplementedError(
"ECDSA certificates with unnamed curves are unsupported "
"at this time"
)
curve_name = backend._lib.OBJ_nid2sn(nid)
backend.openssl_assert(curve_name != backend._ffi.NULL)
sn = backend._ffi.string(curve_name).decode('ascii')
return sn
def _mark_asn1_named_ec_curve(backend, ec_cdata):
"""
Set the named curve flag on the EC_KEY. This causes OpenSSL to
serialize EC keys along with their curve OID which makes
deserialization easier.
"""
backend._lib.EC_KEY_set_asn1_flag(
ec_cdata, backend._lib.OPENSSL_EC_NAMED_CURVE
)
def _sn_to_elliptic_curve(backend, sn):
try:
return ec._CURVE_TYPES[sn]()
except KeyError:
raise UnsupportedAlgorithm(
"{0} is not a supported elliptic curve".format(sn),
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
)
@utils.register_interface(AsymmetricSignatureContext)
class _ECDSASignatureContext(object):
def __init__(self, backend, private_key, algorithm):
self._backend = backend
self._private_key = private_key
self._digest = hashes.Hash(algorithm, backend)
def update(self, data):
self._digest.update(pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
This file is part of ChibiOS.
ChibiOS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file chfactory.c
* @brief ChibiOS objects factory and registry code.
*
* @addtogroup oslib_objects_factory
* @details The object factory is a subsystem that allows to:
* - Register static objects by name.
* - Dynamically create objects and assign them a name.
* - Retrieve existing objects by name.
* - Free objects by reference.
* .
* Allocated OS objects are handled using a reference counter, only
* when all references have been released then the object memory is
* freed in a pool.<br>
* @pre This subsystem requires the @p CH_CFG_USE_MEMCORE and
* @p CH_CFG_USE_MEMPOOLS options to be set to @p TRUE. The
* option @p CH_CFG_USE_HEAP is also required if the support
* for variable length objects is enabled.
* @note Compatible with RT and NIL.
* @{
*/
#include <string.h>
#include "ch.h"
#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*
* Defaults on the best synchronization mechanism available.
*/
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
#define F_LOCK() chMtxLock(&ch_factory.mtx)
#define F_UNLOCK() chMtxUnlock(&ch_factory.mtx)
#else
#define F_LOCK() (void) chSemWait(&ch_factory.sem)
#define F_UNLOCK() chSemSignal(&ch_factory.sem)
#endif
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/**
* @brief Factory object static instance.
* @note It is a global object because it could be accessed through
* a specific debugger plugin.
*/
objects_factory_t ch_factory;
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
static inline void dyn_list_init(dyn_list_t *dlp) {
dlp->next = (dyn_element_t *)dlp;
}
static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) {
dyn_element_t *p = dlp->next;
while (p != (dyn_element_t *)dlp) {
if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH) == 0) {
return p;
}
p = p->next;
}
return NULL;
}
static dyn_element_t *dyn_list_unlink(dyn_element_t *element,
dyn_list_t *dlp) {
dyn_element_t *prev = (dyn_element_t *)dlp;
/* Scanning the list.*/
while (prev->next != (dyn_element_t *)dlp) {
if (prev->next == element) {
/* Found.*/
prev->next = element->next;
return element;
}
/* Next element in the list.*/
prev = prev->next;
}
return NULL;
}
#if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__)
static dyn_element_t *dyn_create_object_heap(const char *name,
dyn_list_t *dlp,
size_t size) {
dyn_element_t *dep;
chDbgCheck(name != NULL);
/* Checking if an object with this name has already been created.*/
dep = dyn_list_find(name, dlp);
if (dep != NULL) {
return NULL;
}
/* Allocating space for the new buffer object.*/
/*lint -save -e668 [] Lint is confused by the above chDbgCheck() and
incorrectly assumes that strncpy() could receive a NULL pointer.*/
dep = (dyn_element_t *)chHeapAlloc(NULL, size);
if (dep == NULL) {
return NULL;
}
/* Initializing object list element.*/
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH);
/*lint -restore*/
dep->refs = (ucnt_t)1;
dep->next = dlp->next;
/* Updating factory list.*/
dlp->next = dep;
return dep;
}
static void dyn_release_object_heap(dyn_element_t *dep,
dyn_list_t *dlp) {
chDbgCheck(dep != NULL);
chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
dep->refs--;
if (dep->refs == (ucnt_t)0) {
dep = dyn_list_unlink(dep, dlp);
chHeapFree((void *)dep);
}
}
#endif /* CH_FACTORY_REQUIRES_HEAP */
#if CH_FACTORY_REQUIRES_POOLS || defined(__DOXYGEN__)
static dyn_element_t *dyn_create_object_pool(const char *name,
dyn_list_t *dlp,
memory_pool_t *mp) {
dyn_element_t *dep;
chDbgCheck(name != NULL);
/* Checking if an object object with this name has already been created.*/
dep = dyn_list_find(name, dlp);
if (dep != NULL) {
return NULL;
}
/* Allocating space for the new object.*/
dep = (dyn_element_t *)chPoolAlloc(mp);
if (dep == NULL) {
return NULL;
}
/* Initializing object list element.*/
/*lint -save -e668 [] Lint is confused by the above chDbgCheck() and
incorrectly assumes that strncpy() could receive a NULL pointer.*/
strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH);
/*lint -restore*/
dep->refs = (ucnt_t)1;
dep->next = dlp->next;
/* Updating factory list.*/
dlp->next = (dyn_element_t *)dep;
return dep;
}
static void dyn_release_object_pool(dyn_element_t *dep,
dyn_list_t *dlp,
memory_pool_t *mp) {
chDbgCheck(dep != NULL);
chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
dep->refs--;
if (dep->refs == (ucnt_t)0) {
dep = dyn_list_unlink(dep, dlp);
chPoolFree(mp, (void *)dep);
}
}
#endif /* CH_FACTORY_REQUIRES_POOLS */
static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
dyn_element_t *dep;
chDbgCheck(name != NULL);
/* Checking if an object with this name has already been created.*/
dep = dyn_list_find(name, dlp);
if (dep != NULL) {
/* Increasing references counter.*/
dep->refs++;
}
return dep;
}
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief Initializes the objects factory.
*
* @init
*/
void _factory_init(void) {
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
chMtxObjectInit(&ch_factory.mtx);
#else
chSemObjectInit(&ch_factory.sem, (cnt_t)1);
#endif
#if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
dyn_list_init(&ch_factory.obj_list);
chPoolObjectInit(&ch_factory.obj_pool,
sizeof (registered_object_t),
chCoreAllocAlignedI);
#endif
#if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
dyn_list_init(&ch_factory.buf_list);
#endif
#if CH_CFG_FACTORY_SEMAPHORES == TRUE
dyn_list_init(&ch_factory.sem_list);
chPoolObjectInit(&ch_factory.sem_pool,
sizeof (dyn_semaphore_t),
chCoreAllocAlignedI);
#endif
#if CH_CFG_FACTORY_MAILBOXES == TRUE
dyn_list_init(&ch_factory.mbx_list);
#endif
#if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
dyn_list_init(&ch_factory.fifo_list);
#endif
#if CH_CFG_FACTORY_PIPES == TRUE
dyn_list_init(&ch_factory.pipe_list);
#endif
}
#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
/**
* @brief Registers a generic object.
* @post A reference to the registered object is returned and the
* reference counter is initialized to one.
*
* @param[in] name name to be assigned to the registered object
* @param[in] objp pointer to the object to be registered
*
* @return The reference to the registered object.
* @retval NULL if the object to be registered cannot be allocated or
* a registered object with the same name exists.
*
* @api
*/
registered_object_t *chFactoryRegisterObject(const char *name,
void *objp) {
registered_object_t *rop;
F_LOCK();
rop = (registered_object_t *)dyn_create_object_pool(name,
&ch_factory.obj_list,
&ch_factory.obj_pool);
if (rop != NULL) {
/* Initializing registered object data.*/
rop->objp = objp;
}
F_UNLOCK();
return rop;
}
/**
* @brief Retrieves a registered object.
* @post A reference to the registered object is returned with the
* reference counter increased by one.
*
* @param[in] name name of the registered object
*
* @return The reference to the found registered object.
* @retval NULL if a registered object with the specified name
* does not exist.
*
* @api
*/
registered_object_t *chFactoryFindObject(const char *name) {
registered_object_t *rop;
F_LOCK();
rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
F_UNLOCK();
return rop;
}
/**
* @brief Retrieves a registered object by pointer.
* @post A reference to the registered object is returned with the
* reference counter increased by one.
*
* @param[in] objp pointer to the object to be retrieved
*
* @return The reference to the found registered object.
* @retval NULL if a registered object with the specified pointer
* does not exist.
*
* @api
*/
registered_object_t *chFactoryFindObjectByPointer(void *objp) {
registered_object_t *rop = (registered_object_t *)ch_factory.obj_list.next;
F_LOCK();
while ((void *)rop != (void *)&ch_factory.obj_list) {
if (rop->objp == objp) {
rop->element.refs++;
F_UNLOCK();
return rop;
}
rop = (registered_object_t *)rop->element.next;
}
F_UNLOCK();
return NULL;
}
/**
* @brief Releases a registered object.
* @details The reference counter of the registered object is decreased
* by one, if reaches zero then the registered object memory
* is freed.
* @note The object itself is not freed, it could be static, only the
* allocated list element is freed.
*
* @param[in] rop registered object reference
*
* @api
*/
void chFactoryReleaseObject(registered_object_t *rop){
F_LOCK();
dyn_release_object_pool(&rop->element,
&ch_factory.obj_list,
&ch_factory.obj_pool);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
/**
* @brief Creates a generic dynamic buffer object.
* @post A reference to the dynamic buffer object is returned and the
* reference counter is initialized to one.
* @post The dynamic buffer object is filled with zeros.
*
* @param[in] name name to be assigned to the new dynamic buffer object
* @param[in] size payload size of the dynamic buffer object to be created
*
* @return The reference to the created dynamic buffer object.
* @retval NULL if the dynamic buffer object cannot be allocated or
* a dynamic buffer object with the same name exists.
*
* @api
*/
dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
dyn_buffer_t *dbp;
F_LOCK();
dbp = (dyn_buffer_t *)dyn_create_object_heap(name,
&ch_factory.buf_list,
size);
if (dbp != NULL) {
/* Initializing buffer object data.*/
memset((void *)dbp->buffer, 0, size);
}
F_UNLOCK();
return dbp;
}
/**
* @brief Retrieves a dynamic buffer object.
* @post A reference to the dynamic buffer object is returned with the
* reference counter increased by one.
*
* @param[in] name name of the dynamic buffer object
*
* @return The reference to the found dynamic buffer object.
* @retval NULL if a dynamic buffer object with the specified name
* does not exist.
*
* @api
*/
dyn_buffer_t *chFactoryFindBuffer(const char *name) {
dyn_buffer_t *dbp;
F_LOCK();
dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
F_UNLOCK();
return dbp;
}
/**
* @brief Releases a dynamic buffer object.
* @details The reference counter of the dynamic buffer object is decreased
* by one, if reaches zero then the dynamic buffer object memory
* is freed.
*
* @param[in] dbp dynamic buffer object reference
*
* @api
*/
void chFactoryReleaseBuffer(dyn_buffer_t *dbp) {
F_LOCK();
dyn_release_object_heap(&dbp->element, &ch_factory.buf_list);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
/**
* @brief Creates a dynamic semaphore object.
* @post A reference to the dynamic semaphore object is returned and the
* reference counter is initialized to one.
* @post The dynamic semaphore object is initialized and ready to use.
*
* @param[in] name name to be assigned to the new dynamic semaphore object
* @param[in] n dynamic semaphore object counter initialization value
*
* @return The reference to the created dynamic semaphore object.
* @retval NULL if the dynamic semaphore object cannot be allocated or
* a dynamic semaphore with the same name exists.
*
* @api
*/
dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
dyn_semaphore_t *dsp;
F_LOCK();
dsp = (dyn_semaphore_t *)dyn_create_object_pool(name,
&ch_factory.sem_list,
&ch_factory.sem_pool);
if (dsp != NULL) {
/* Initializing semaphore object dataa.*/
chSemObjectInit(&dsp->sem, n);
}
F_UNLOCK();
return dsp;
}
/**
* @brief Retrieves a dynamic semaphore object.
* @post A reference to the dynamic semaphore object is returned with the
* reference counter increased by one.
*
* @param[in] name name of the dynamic semaphore object
*
* @return The reference to the found dynamic semaphore object.
* @retval NULL if a dynamic semaphore object with the specified name
* does not exist.
*
* @api
*/
dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
dyn_semaphore_t *dsp;
F_LOCK();
dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
F_UNLOCK();
return dsp;
}
/**
* @brief Releases a dynamic semaphore object.
* @details The reference counter of the dynamic semaphore object is decreased
* by one, if reaches zero then the dynamic semaphore object memory
* is freed.
*
* @param[in] dsp dynamic semaphore object reference
*
* @api
*/
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
F_LOCK();
dyn_release_object_pool(&dsp->element,
&ch_factory.sem_list,
&ch_factory.sem_pool);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXIGEN__)
/**
* @brief Creates a dynamic mailbox object.
* @post A reference to the dynamic mailbox object is returned and the
* reference counter is initialized to one.
* @post The dynamic mailbox object is initialized and ready to use.
*
* @param[in] name name to be assigned to the new dynamic mailbox object
* @param[in] n mailbox buffer size as number of messages
*
* @return The reference to the created dynamic mailbox object.
* @retval NULL if the dynamic mailbox object cannot be allocated or
* a dynamic mailbox object with the same name exists.
*
* @api
*/
dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n) {
dyn_mailbox_t *dmp;
F_LOCK();
dmp = (dyn_mailbox_t *)dyn_create_object_heap(name,
&ch_factory.mbx_list,
sizeof (dyn_mailbox_t) +
(n * sizeof (msg_t)));
if (dmp != NULL) {
/* Initializing mailbox object data.*/
chMBObjectInit(&dmp->mbx, dmp->msgbuf, n);
}
F_UNLOCK();
return dmp;
}
/**
* @brief Retrieves a dynamic mailbox object.
* @post A reference to the dynamic mailbox object is returned with the
* reference counter increased by one.
*
* @param[in] name name of the dynamic mailbox object
*
* @return The reference to the found dynamic mailbox object.
* @retval NULL if a dynamic mailbox object with the specified name
* does not exist.
*
* @api
*/
dyn_mailbox_t *chFactoryFindMailbox(const char *name) {
dyn_mailbox_t *dmp;
F_LOCK();
dmp = (dyn_mailbox_t *)dyn_find_object(name, &ch_factory.mbx_list);
F_UNLOCK();
return dmp;
}
/**
* @brief Releases a dynamic mailbox object.
* @details The reference counter of the dynamic mailbox object is decreased
* by one, if reaches zero then the dynamic mailbox object memory
* is freed.
*
* @param[in] dmp dynamic mailbox object reference
*
* @api
*/
void chFactoryReleaseMailbox(dyn_mailbox_t *dmp) {
F_LOCK();
dyn_release_object_heap(&dmp->element, &ch_factory.mbx_list);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXIGEN__)
/**
* @brief Creates a dynamic "objects FIFO" object.
* @post A reference to the dynamic "objects FIFO" object is returned and
* the reference counter is initialized to one.
* @post The dynamic "objects FIFO" object is initialized and ready to use.
*
* @param[in] name name to be assigned to the new dynamic "objects FIFO"
* object
* @param[in] objsize size of objects
* @param[in] objn number of objects available
* @param[in] objalign required objects alignment
* @return The reference to the created dynamic "objects FIFO"
* object.
* @retval NULL if the dynamic "objects FIFO" object cannot be
* allocated or a dynamic "objects FIFO" object with
* the same name exists.
*
* @api
*/
dyn_objects_fifo_t *chFactoryCreateObjectsFIFO(const char *name,
size_t objsize,
size_t objn,
unsigned objalign) {
dyn_objects_fifo_t *dofp;
F_LOCK();
dofp = (dyn_objects_fifo_t *)dyn_create_object_heap(name,
&ch_factory.fifo_list,
sizeof (dyn_objects_fifo_t) +
(objn * sizeof (msg_t)) +
(objn * objsize));
if (dofp != NULL) {
/* Initializing mailbox object data.*/
chFifoObjectInit(&dofp->fifo, objsize, objn, objalign,
(void *)&dofp->msgbuf[objn], dofp->msgbuf);
}
F_UNLOCK();
return dofp;
}
/**
* @brief Retrieves a dynamic "objects FIFO" object.
* @post A reference to the dynamic "objects FIFO" object is returned with
* the reference counter increased by one.
*
* @param[in] name name of the dynamic "objects FIFO" object
*
* @return The reference to the found dynamic "objects FIFO"
* object.
* @retval NULL if a dynamic "objects FIFO" object with the specified
* name does not exist.
*
* @api
*/
dyn_objects_fifo_t *chFactoryFindObjectsFIFO(const char *name) {
dyn_objects_fifo_t *dofp;
F_LOCK();
dofp = (dyn_objects_fifo_t *)dyn_find_object(name, &ch_factory.fifo_list);
F_UNLOCK();
return dofp;
}
/**
* @brief Releases a dynamic "objects FIFO" object.
* @details The reference counter of the dynamic "objects FIFO" object is
* decreased by one, if reaches zero then the dynamic "objects FIFO"
* object memory is freed.
*
* @param[in] dofp dynamic "objects FIFO" object reference
*
* @api
*/
void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp) {
F_LOCK();
dyn_release_object_heap(&dofp->element, &ch_factory.fifo_list);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXIGEN__)
/**
* @brief Creates a dynamic pipe object.
* @post A reference to the dynamic pipe object is returned and
* the reference counter is initialized to one.
* @post The dynamic pipe object is initialized and ready to use.
*
* @param[in] name name to be assigned to the new dynamic pipe
* object
* @param[in] size pipe buffer size
* @return The reference to the created dynamic pipe
* object.
* @retval NULL if the dynamic pipe object cannot be
* allocated or a dynamic pipe object with
* the same name exists.
*
* @api
*/
dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size) {
dyn_pipe_t *dpp;
F_LOCK();
dpp = (dyn_pipe_t *)dyn_create_object_heap(name,
&ch_factory.pipe_list,
sizeof (dyn_pipe_t) + size);
if (dpp != NULL) {
/* Initializing mailbox object data.*/
chPipeObjectInit(&dpp->pipe, dpp->buffer, size);
}
F_UNLOCK();
return dpp;
}
/**
* @brief Retrieves a dynamic pipe object.
* @post A reference to the dynamic pipe object is returned with
* the reference counter increased by one.
*
* @param[in] dpp dynamic pipe object reference
*
* @return The reference to the found dynamic pipe
* object.
* @retval NULL if a dynamic pipe object with the specified
* name does not exist.
*
* @api
*/
dyn_pipe_t *chFactoryFindPipe(const char *name) {
dyn_pipe_t *dpp;
F_LOCK();
dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.pipe_list);
F_UNLOCK();
return dpp;
}
/**
* @brief Releases a dynamic pipe object.
* @details The reference counter of the dynamic pipe object is
* decreased by one, if reaches zero then the dynamic pipe
* object memory is freed.
*
* @param[in] dpp dynamic pipe object reference
*
* @api
*/
void chFactoryReleasePipe(dyn_pipe_t *dpp) {
F_LOCK();
dyn_release_object_heap(&dpp->element, &ch_factory.pipe_list);
F_UNLOCK();
}
#endif /* CH_CFG_FACTORY_PIPES = TRUE */
#endif /* CH_CFG_USE_FACTORY == TRUE */
/** @} */