Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
lwip_snmp_threadsync.c
00001 /** 00002 * @file 00003 * SNMP thread synchronization implementation. 00004 */ 00005 00006 /* 00007 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without modification, 00011 * are permitted provided that the following conditions are met: 00012 * 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. The name of the author may not be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00024 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00026 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00029 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00030 * OF SUCH DAMAGE. 00031 * 00032 * Author: Dirk Ziegelmeier <dziegel@gmx.de> 00033 */ 00034 00035 #include "lwip/apps/snmp_opts.h" 00036 00037 #if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */ 00038 00039 #include "lwip/apps/snmp_threadsync.h" 00040 #include "lwip/apps/snmp_core.h" 00041 #include "lwip/sys.h" 00042 #include <string.h> 00043 00044 static void 00045 call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn) 00046 { 00047 sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex); 00048 call_data->threadsync_node->instance->sync_fn(fn, call_data); 00049 sys_sem_wait(&call_data->threadsync_node->instance->sem); 00050 sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex); 00051 } 00052 00053 static void 00054 threadsync_get_value_synced(void *ctx) 00055 { 00056 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00057 00058 call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value); 00059 00060 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00061 } 00062 00063 static s16_t 00064 threadsync_get_value(struct snmp_node_instance* instance, void* value) 00065 { 00066 struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; 00067 00068 call_data->arg1.value = value; 00069 call_synced_function(call_data, threadsync_get_value_synced); 00070 00071 return call_data->retval.s16; 00072 } 00073 00074 static void 00075 threadsync_set_test_synced(void *ctx) 00076 { 00077 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00078 00079 call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); 00080 00081 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00082 } 00083 00084 static snmp_err_t 00085 threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value) 00086 { 00087 struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; 00088 00089 call_data->arg1.value = value; 00090 call_data->arg2.len = len; 00091 call_synced_function(call_data, threadsync_set_test_synced); 00092 00093 return call_data->retval.err; 00094 } 00095 00096 static void 00097 threadsync_set_value_synced(void *ctx) 00098 { 00099 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00100 00101 call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); 00102 00103 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00104 } 00105 00106 static snmp_err_t 00107 threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value) 00108 { 00109 struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; 00110 00111 call_data->arg1.value = value; 00112 call_data->arg2.len = len; 00113 call_synced_function(call_data, threadsync_set_value_synced); 00114 00115 return call_data->retval.err; 00116 } 00117 00118 static void 00119 threadsync_release_instance_synced(void* ctx) 00120 { 00121 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00122 00123 call_data->proxy_instance.release_instance(&call_data->proxy_instance); 00124 00125 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00126 } 00127 00128 static void 00129 threadsync_release_instance(struct snmp_node_instance *instance) 00130 { 00131 struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; 00132 00133 if (call_data->proxy_instance.release_instance != NULL) { 00134 call_synced_function(call_data, threadsync_release_instance_synced); 00135 } 00136 } 00137 00138 static void 00139 get_instance_synced(void* ctx) 00140 { 00141 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00142 const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; 00143 00144 call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); 00145 00146 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00147 } 00148 00149 static void 00150 get_next_instance_synced(void* ctx) 00151 { 00152 struct threadsync_data *call_data = (struct threadsync_data*)ctx; 00153 const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; 00154 00155 call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); 00156 00157 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00158 } 00159 00160 static snmp_err_t 00161 do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn) 00162 { 00163 const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)(const void*)instance->node; 00164 struct threadsync_data *call_data = &threadsync_node->instance->data; 00165 00166 if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) { 00167 LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID")); 00168 return SNMP_ERR_NOSUCHINSTANCE; 00169 } 00170 00171 memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance)); 00172 00173 instance->reference.ptr = call_data; 00174 snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len); 00175 00176 call_data->proxy_instance.node = &threadsync_node->target->node; 00177 call_data->threadsync_node = threadsync_node; 00178 00179 call_data->arg1.root_oid = root_oid; 00180 call_data->arg2.root_oid_len = root_oid_len; 00181 call_synced_function(call_data, fn); 00182 00183 if (call_data->retval.err == SNMP_ERR_NOERROR) { 00184 instance->access = call_data->proxy_instance.access; 00185 instance->asn1_type = call_data->proxy_instance.asn1_type; 00186 instance->release_instance = threadsync_release_instance; 00187 instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL; 00188 instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL; 00189 instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL; 00190 snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len); 00191 } 00192 00193 return call_data->retval.err; 00194 } 00195 00196 snmp_err_t 00197 snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) 00198 { 00199 return do_sync(root_oid, root_oid_len, instance, get_instance_synced); 00200 } 00201 00202 snmp_err_t 00203 snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) 00204 { 00205 return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced); 00206 } 00207 00208 /** Initializes thread synchronization instance */ 00209 void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn) 00210 { 00211 err_t err = sys_mutex_new(&instance->sem_usage_mutex); 00212 LWIP_ASSERT("Failed to set up mutex", err == ERR_OK); 00213 err = sys_sem_new(&instance->sem, 0); 00214 LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK); 00215 instance->sync_fn = sync_fn; 00216 } 00217 00218 #endif /* LWIP_SNMP */
Generated on Tue Jul 12 2022 13:15:54 by
