00001 /* 00002 * Copyright (c) 2005, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * @(#)$Id: service.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ 00032 */ 00033 00034 /** \addtogroup sys 00035 * @{ 00036 */ 00037 00038 /** 00039 * \defgroup service The Contiki service mechanism 00040 * 00041 * The Contiki service mechanism enables cross-process functions. A 00042 * service that is registered by one process can be accessed by other 00043 * processes in the system. Services can be transparently replaced at 00044 * run-time. 00045 * 00046 * A service has an interface that callers use to access the service's 00047 * functions. This interface typically is defined in a header file 00048 * that is included by all users of the service. A service interface 00049 * is defined with the SERVICE_INTERFACE() macro. 00050 * 00051 * A service implementation is declared with the SERVICE() macro. The 00052 * SERVICE() statement specifies the actual functions that are used to 00053 * implement the service. 00054 * 00055 * Every service has a controlling process. The controlling process 00056 * registers the service with the system when it starts, and is also 00057 * notified if the service is removed or replaced. A process may 00058 * register any number of services. 00059 * 00060 * Service registration is done with a SERVICE_REGISTER() 00061 * statement. If a service with the same name is already registered, 00062 * this is removed before the new service is registered. 00063 * 00064 * The SERVICE_CALL() macro is used to call a service. If the service 00065 * to be called is not registered, the SERVICE_CALL() statement does 00066 * nothing. The SERVICE_FIND() function can be used to check if a 00067 * particular service exists before calling SERVICE_CALL(). 00068 * 00069 * @{ 00070 */ 00071 00072 /** 00073 * \file 00074 * Header file for the Contiki service mechanism. 00075 * \author 00076 * Adam Dunkels <adam@sics.se> 00077 */ 00078 00079 #ifndef __SERVICE_H__ 00080 #define __SERVICE_H__ 00081 00082 #include "contiki.h" 00083 00084 struct service { 00085 struct service *next; 00086 struct process *p; 00087 const char *name; 00088 const void *interface; 00089 }; 00090 00091 /** 00092 * \name Service declaration and defition 00093 * @{ 00094 */ 00095 00096 /** 00097 * Define the name and interface of a service. 00098 * 00099 * This statement defines the name and interface of a service. 00100 * 00101 * \param name The name of the service. 00102 * 00103 * \param interface A list of function declarations that comprises the 00104 * service interface. This list must be enclosed by curly brackets and 00105 * consist of declarations of function pointers separated by 00106 * semicolons. 00107 * 00108 * \hideinitializer 00109 */ 00110 #define SERVICE_INTERFACE(name, interface) struct name interface; 00111 00112 #if ! CC_NO_VA_ARGS 00113 /** 00114 * \brief Define an implementation of a service interface. 00115 * \param name The name of this particular instance of the service, for use with SERVICE_REGISTER(). 00116 * \param service_name The name of the service, from the SERVICE_INTERFACE(). 00117 * \param ... A structure containing the functions that implements the service. 00118 * 00119 * This statement defines the name of this implementation 00120 * of the service and defines the functions that actually 00121 * implement the functions offered by the service. 00122 * 00123 * \hideinitializer 00124 */ 00125 #define SERVICE(name, service_name, ...) \ 00126 static struct service_name name##_interface = __VA_ARGS__ ; \ 00127 struct service name = { NULL, NULL, service_name##_name, & name##_interface } 00128 #endif 00129 00130 /** @} */ 00131 00132 /** 00133 * \name Calling a service 00134 * @{ 00135 */ 00136 00137 /** 00138 * Call a function from a specified service, if it is registered. 00139 * 00140 * 00141 * \param service_name The name of the service that is to be called. 00142 * 00143 * \param function The function that is to be called. This is a full 00144 * function call, including parameters. 00145 * 00146 * \hideinitializer 00147 */ 00148 #define SERVICE_CALL(service_name, function) \ 00149 { \ 00150 struct service *service_s; \ 00151 service_s = service_find(service_name##_name); \ 00152 if(service_s != NULL) { \ 00153 ((const struct service_name *)service_s->interface)->function; \ 00154 } \ 00155 } 00156 00157 /* @} */ 00158 00159 #define SERVICE_EXISTS(service_name) (service_find(service_name##_name) != NULL) 00160 00161 /** 00162 * \name Service registration and removal 00163 * @{ 00164 */ 00165 00166 /** 00167 * Register a service. 00168 * 00169 * \hideinitializer 00170 */ 00171 #define SERVICE_REGISTER(name) service_register(&name) 00172 00173 /** 00174 * Remove a service. 00175 * 00176 * \hideinitializer 00177 */ 00178 #define SERVICE_REMOVE(service_name) service_remove(&service_name) 00179 00180 /** @} */ 00181 00182 /** 00183 * Find service. 00184 * 00185 * \hideinitializer 00186 */ 00187 #define SERVICE_FIND(service_name) service_find(service_name##_name) 00188 00189 void service_register(struct service *s); 00190 void service_remove(struct service *s); 00191 struct service *service_find(const char *name); 00192 00193 #endif /* __SERVICE_H__ */ 00194 /** @} */ 00195 /** @} */