| /******************************************************************************* |
| * Copyright (C) 2004-2006 Intel Corp. All rights reserved. |
| * |
| * 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 Corp. 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 Intel Corp. OR THE 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. |
| *******************************************************************************/ |
| |
| /** |
| * @author Anas Nashif |
| * @author Liang Hou |
| */ |
| #ifdef HAVE_CONFIG_H |
| #include "wsman_config.h" |
| #endif |
| |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <string.h> |
| #ifdef HAVE_PTHREAD_H |
| #include <pthread.h> |
| #endif |
| #ifndef WIN32 |
| #include <dlfcn.h> |
| #endif |
| #include "u/libu.h" |
| #if 0 |
| #include "wsman-faults.h" |
| #include "wsman-xml.h" |
| #include "wsman-plugins.h" |
| #include "wsman-server.h" |
| #include "wsman-dispatcher.h" |
| #endif |
| #include "wsman-soap.h" |
| #include "wsman-soap-envelope.h" |
| #include "wsman-server.h" |
| #include "wsman-xml.h" |
| #include "wsman-dispatcher.h" |
| #include "wsman-event-pool.h" |
| #include "wsman-subscription-repository.h" |
| |
| |
| WsManListenerH *wsman_dispatch_list_new() |
| { |
| WsManListenerH *list = |
| (WsManListenerH *) u_malloc(sizeof(WsManListenerH)); |
| return list; |
| } |
| |
| |
| static int wsman_server_verify_plugin(WsDispatchInterfaceInfo *ifcinfo) |
| { |
| debug("Plugin '%s', version: %s", (ifcinfo->displayName), (ifcinfo->version) ); |
| if (strcmp (OPENWSMAN_PLUGIN_API_VERSION, ifcinfo->version) == 0) { |
| return 1; |
| } |
| return 0; |
| } |
| |
| |
| WsContextH wsman_init_plugins(WsManListenerH * listener) |
| { |
| list_t *list = list_create(LISTCOUNT_T_MAX); |
| lnode_t *node; |
| WsContextH cntx = NULL; |
| WsDispatchInterfaceInfo *ifcinfo = NULL; |
| wsman_plugins_load(listener); |
| node = list_first(listener->plugins); |
| |
| while (node) { |
| WsManPlugin *p = (WsManPlugin *) node->list_data; |
| if (p->init == NULL |
| || p->init(p->p_handle, &(p->data)) == 0 ) { |
| error ("Plugin %s fails init()", p->p_name); |
| error("invalid plugin"); |
| goto next_plugin; |
| } |
| |
| p->ifc = (WsDispatchInterfaceInfo *) |
| malloc(sizeof(WsDispatchInterfaceInfo)); |
| if (p->ifc == NULL) { |
| error("Memory allocation error while loading plugin"); |
| return NULL; |
| } |
| ifcinfo = p->ifc; |
| ifcinfo->extraData = p->data; |
| p->set_config = dlsym(p->p_handle, "set_config"); |
| |
| if (listener->config && p->set_config) { |
| p->set_config(p->p_handle, listener->config); |
| } else { |
| debug("no configuration available for plugin: %s", p->p_name); |
| } |
| |
| if (p->get_endpoints) |
| p->get_endpoints(p->p_handle, p->ifc); |
| |
| if (p->ifc && wsman_server_verify_plugin(ifcinfo)) { |
| lnode_t *i = lnode_create(p->ifc); |
| list_append(list, i); |
| } else { |
| error ("Plugin '%s' is not compatible with version of the software or plugin is invalid", p->p_name); |
| error("invalid plugin"); |
| } |
| next_plugin: |
| node = list_next(listener->plugins, node); |
| } |
| cntx = ws_create_runtime(list); |
| return cntx; |
| } |
| |
| #ifdef ENABLE_EVENTING_SUPPORT |
| SubsRepositoryOpSetH |
| wsman_init_subscription_repository(WsContextH cntx, char *uri) |
| { |
| SoapH soap = ws_context_get_runtime(cntx); |
| if(soap) { |
| soap->subscriptionOpSet = wsman_get_subsrepos_opset(); |
| if(uri) { |
| soap->uri_subsRepository = u_strdup(uri); |
| soap->subscriptionOpSet->init_subscription(uri, NULL); |
| } |
| } |
| return soap->subscriptionOpSet; |
| } |
| |
| EventPoolOpSetH |
| wsman_init_event_pool(WsContextH cntx, void*data) |
| { |
| SoapH soap = ws_context_get_runtime(cntx); |
| if(soap) { |
| soap->eventpoolOpSet = wsman_get_eventpool_opset(); |
| soap->eventpoolOpSet->init(NULL); |
| } |
| return soap->eventpoolOpSet; |
| } |
| |
| int wsman_clean_subsrepository(SoapH soap, SubsRepositoryEntryH entry) |
| { |
| int retVal = 0; |
| WsXmlDocH doc = ws_xml_read_memory( (char *)entry->strdoc, entry->len, "UTF-8", 0); |
| unsigned long expire; |
| WsmanFaultCodeType fault_code; |
| if(doc) { |
| WsXmlNodeH node = ws_xml_get_soap_body(doc); |
| if(node) { |
| node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE); |
| node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_EXPIRES); |
| if(node == NULL) { //No specified expiration, delete it |
| debug("subscription %s deleted from the repository", entry->uuid); |
| soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5); |
| retVal = 1; |
| } |
| else { |
| wsman_set_expiretime(node, &expire, &fault_code); |
| if(fault_code == WSMAN_RC_OK) { |
| if(time_expired(expire)) { |
| debug("subscription %s deleted from the repository", entry->uuid); |
| soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5); |
| retVal = 1; |
| } |
| } |
| } |
| } |
| ws_xml_destroy_doc(doc); |
| } |
| return retVal; |
| } |
| |
| void wsman_repos_notification_dispatcher(WsContextH cntx, SubsRepositoryEntryH entry, int subsNum) |
| { |
| WsmanMessage *wsman_msg = wsman_soap_message_new(); |
| if(wsman_msg == NULL) return; |
| unsigned char *strdoc = entry->strdoc; |
| u_buf_construct(wsman_msg->request, strdoc, entry->len, entry->len); |
| dispatch_inbound_call(cntx->soap, wsman_msg, NULL); |
| wsman_soap_message_destroy(wsman_msg); |
| if(list_count(cntx->subscriptionMemList) > subsNum) { |
| lnode_t *node = list_last(cntx->subscriptionMemList); |
| WsSubscribeInfo *subs = (WsSubscribeInfo *)node->list_data; |
| //Update UUID in the memory |
| strncpy(subs->subsId, entry->uuid+5, EUIDLEN); |
| } |
| } |
| |
| void *wsman_notification_manager(void *arg) |
| { |
| WsContextH cntx = (WsContextH) arg; |
| int r; |
| pthread_mutex_t mutex; |
| pthread_cond_t cond; |
| struct timespec timespec; |
| struct timeval tv; |
| |
| if ((r = pthread_cond_init(&cond, NULL)) != 0) { |
| error("pthread_cond_init failed = %d", r); |
| return NULL; |
| } |
| if ((r = pthread_mutex_init(&mutex, NULL)) != 0) { |
| error("pthread_mutex_init failed = %d", r); |
| return NULL; |
| } |
| |
| while (continue_working) { |
| pthread_mutex_lock(&mutex); |
| gettimeofday(&tv, NULL); |
| timespec.tv_sec = tv.tv_sec + 1; |
| timespec.tv_nsec = tv.tv_usec * 1000; |
| pthread_cond_timedwait(&cond, &mutex, ×pec); |
| pthread_mutex_unlock(&mutex); |
| wse_notification_manager(cntx); |
| } |
| return NULL; |
| } |
| #endif |
| void *wsman_server_auxiliary_loop_thread(void *arg) |
| { |
| WsContextH cntx = (WsContextH) arg; |
| int r; |
| pthread_mutex_t mutex; |
| pthread_cond_t cond; |
| struct timespec timespec; |
| struct timeval tv; |
| |
| if ((r = pthread_cond_init(&cond, NULL)) != 0) { |
| error("pthread_cond_init failed = %d", r); |
| return NULL; |
| } |
| if ((r = pthread_mutex_init(&mutex, NULL)) != 0) { |
| error("pthread_mutex_init failed = %d", r); |
| return NULL; |
| } |
| |
| while (continue_working) { |
| pthread_mutex_lock(&mutex); |
| gettimeofday(&tv, NULL); |
| timespec.tv_sec = tv.tv_sec + 1; |
| timespec.tv_nsec = tv.tv_usec * 1000; |
| pthread_cond_timedwait(&cond, &mutex, ×pec); |
| pthread_mutex_unlock(&mutex); |
| |
| wsman_timeouts_manager(cntx, NULL); |
| #ifdef ENABLE_EVENTING_SUPPORT |
| wsman_heartbeat_generator(cntx, NULL); |
| #endif |
| } |
| return NULL; |
| } |
| |
| |