2006-06-18 00:41:10 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2005, Swedish Institute of Computer Science
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. 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.
|
|
|
|
* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
|
|
|
|
*
|
|
|
|
* This file is part of the Contiki operating system.
|
|
|
|
*
|
2006-09-10 01:24:39 +02:00
|
|
|
* @(#)$Id: service.h,v 1.2 2006/09/09 23:25:07 oliverschmidt Exp $
|
2006-06-18 00:41:10 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/** \addtogroup sys
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \defgroup service The Contiki service mechanism
|
|
|
|
*
|
|
|
|
* The Contiki service mechanism enables cross-process functions. A
|
|
|
|
* service that is registered by one process can be accessed by other
|
|
|
|
* processes in the system. Services can be transparently replaced at
|
|
|
|
* run-time.
|
|
|
|
*
|
|
|
|
* A service has an interface that callers use to access the service's
|
|
|
|
* functions. This interface typically is defined in a header file
|
|
|
|
* that is included by all users of the service. A service interface
|
|
|
|
* is defined with the SERVICE_INTERFACE() macro.
|
|
|
|
*
|
|
|
|
* A service implementation is declared with the SERVICE() macro. The
|
|
|
|
* SERVICE() statement specifies the actual functions that are used to
|
|
|
|
* implement the service.
|
|
|
|
*
|
|
|
|
* Every service has a controlling process. The controlling process
|
|
|
|
* registers the service with the system when it starts, and is also
|
|
|
|
* notified if the service is removed or replaced. A process may
|
|
|
|
* register any number of services.
|
|
|
|
*
|
|
|
|
* Service registration is done with a SERVICE_REGISTER()
|
|
|
|
* statement. If a service with the same name is already registered,
|
|
|
|
* this is removed before the new service is registered.
|
|
|
|
*
|
|
|
|
* The SERVICE_CALL() macro is used to call a service. If the service
|
|
|
|
* to be called is not registered, the SERVICE_CALL() statement does
|
|
|
|
* nothing. The SERVICE_FIND() function can be used to check if a
|
|
|
|
* particular service exists before calling SERVICE_CALL().
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
* Header file for the Contiki service mechanism.
|
|
|
|
* \author
|
|
|
|
* Adam Dunkels <adam@sics.se>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SERVICE_H__
|
|
|
|
#define __SERVICE_H__
|
|
|
|
|
|
|
|
#include "contiki.h"
|
|
|
|
|
|
|
|
struct service {
|
|
|
|
struct service *next;
|
|
|
|
struct process *p;
|
|
|
|
const char *name;
|
|
|
|
const void *interface;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Service declaration and defition
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Define the name and interface of a service.
|
|
|
|
*
|
|
|
|
* This statement defines the name and interface of a service.
|
|
|
|
*
|
|
|
|
* \param name The name of the service.
|
|
|
|
*
|
|
|
|
* \param interface A list of function declarations that comprises the
|
|
|
|
* service interface. This list must be enclosed by curly brackets and
|
|
|
|
* consist of declarations of function pointers separated by
|
|
|
|
* semicolons.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE_INTERFACE(name, interface) struct name interface;
|
|
|
|
|
|
|
|
#if ! CC_NO_VA_ARGS
|
|
|
|
/**
|
|
|
|
* \brief Define an implementation of a service interface.
|
|
|
|
* \param name The name of this particular instance of the service, for use with SERVICE_REGISTER().
|
|
|
|
* \param service_name The name of the service, from the SERVICE_INTERFACE().
|
|
|
|
* \param ... A structure containing the functions that implements the service.
|
|
|
|
*
|
|
|
|
* This statement defines the name of this implementation
|
|
|
|
* of the service and defines the functions that actually
|
|
|
|
* implement the functions offered by the service.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE(name, service_name, ...) \
|
|
|
|
static struct service_name name##_interface = __VA_ARGS__ ; \
|
|
|
|
struct service name = { NULL, NULL, service_name##_name, & name##_interface }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Calling a service
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call a function from a specified service, if it is registered.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* \param service_name The name of the service that is to be called.
|
|
|
|
*
|
|
|
|
* \param function The function that is to be called. This is a full
|
|
|
|
* function call, including parameters.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE_CALL(service_name, function) \
|
|
|
|
{ \
|
|
|
|
struct service *service_s; \
|
|
|
|
service_s = service_find(service_name##_name); \
|
|
|
|
if(service_s != NULL) { \
|
|
|
|
((const struct service_name *)service_s->interface)->function; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* @} */
|
|
|
|
|
|
|
|
#define SERVICE_EXISTS(service_name) (service_find(service_name##_name) != NULL)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Service registration and removal
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register a service.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE_REGISTER(name) service_register(&name)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a service.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE_REMOVE(service_name) service_remove(&service_name)
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find service.
|
|
|
|
*
|
|
|
|
* \hideinitializer
|
|
|
|
*/
|
|
|
|
#define SERVICE_FIND(service_name) service_find(service_name##_name)
|
|
|
|
|
2006-09-10 01:24:39 +02:00
|
|
|
CCIF void service_register(struct service *s);
|
|
|
|
CCIF void service_remove(struct service *s);
|
2006-06-18 00:41:10 +02:00
|
|
|
struct service *service_find(const char *name);
|
|
|
|
|
|
|
|
#endif /* __SERVICE_H__ */
|
|
|
|
/** @} */
|
|
|
|
/** @} */
|