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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 if (call_data->proxy_instance.get_value != NULL) { 00059 call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value); 00060 } else { 00061 call_data->retval.s16 = -1; 00062 } 00063 00064 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00065 } 00066 00067 static s16_t 00068 threadsync_get_value(struct snmp_node_instance *instance, void *value) 00069 { 00070 struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr; 00071 00072 call_data->arg1.value = value; 00073 call_synced_function(call_data, threadsync_get_value_synced); 00074 00075 return call_data->retval.s16; 00076 } 00077 00078 static void 00079 threadsync_set_test_synced(void *ctx) 00080 { 00081 struct threadsync_data *call_data = (struct threadsync_data *)ctx; 00082 00083 if (call_data->proxy_instance.set_test != NULL) { 00084 call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); 00085 } else { 00086 call_data->retval.err = SNMP_ERR_NOTWRITABLE; 00087 } 00088 00089 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00090 } 00091 00092 static snmp_err_t 00093 threadsync_set_test(struct snmp_node_instance *instance, u16_t len, void *value) 00094 { 00095 struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr; 00096 00097 call_data->arg1.value = value; 00098 call_data->arg2.len = len; 00099 call_synced_function(call_data, threadsync_set_test_synced); 00100 00101 return call_data->retval.err; 00102 } 00103 00104 static void 00105 threadsync_set_value_synced(void *ctx) 00106 { 00107 struct threadsync_data *call_data = (struct threadsync_data *)ctx; 00108 00109 if (call_data->proxy_instance.set_value != NULL) { 00110 call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); 00111 } else { 00112 call_data->retval.err = SNMP_ERR_NOTWRITABLE; 00113 } 00114 00115 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00116 } 00117 00118 static snmp_err_t 00119 threadsync_set_value(struct snmp_node_instance *instance, u16_t len, void *value) 00120 { 00121 struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr; 00122 00123 call_data->arg1.value = value; 00124 call_data->arg2.len = len; 00125 call_synced_function(call_data, threadsync_set_value_synced); 00126 00127 return call_data->retval.err; 00128 } 00129 00130 static void 00131 threadsync_release_instance_synced(void *ctx) 00132 { 00133 struct threadsync_data *call_data = (struct threadsync_data *)ctx; 00134 00135 call_data->proxy_instance.release_instance(&call_data->proxy_instance); 00136 00137 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00138 } 00139 00140 static void 00141 threadsync_release_instance(struct snmp_node_instance *instance) 00142 { 00143 struct threadsync_data *call_data = (struct threadsync_data *)instance->reference.ptr; 00144 00145 if (call_data->proxy_instance.release_instance != NULL) { 00146 call_synced_function(call_data, threadsync_release_instance_synced); 00147 } 00148 } 00149 00150 static void 00151 get_instance_synced(void *ctx) 00152 { 00153 struct threadsync_data *call_data = (struct threadsync_data *)ctx; 00154 const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node *)(const void *)call_data->proxy_instance.node; 00155 00156 call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); 00157 00158 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00159 } 00160 00161 static void 00162 get_next_instance_synced(void *ctx) 00163 { 00164 struct threadsync_data *call_data = (struct threadsync_data *)ctx; 00165 const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node *)(const void *)call_data->proxy_instance.node; 00166 00167 call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); 00168 00169 sys_sem_signal(&call_data->threadsync_node->instance->sem); 00170 } 00171 00172 static snmp_err_t 00173 do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance, snmp_threadsync_called_fn fn) 00174 { 00175 const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node *)(const void *)instance->node; 00176 struct threadsync_data *call_data = &threadsync_node->instance->data; 00177 00178 if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) { 00179 LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID")); 00180 return SNMP_ERR_NOSUCHINSTANCE; 00181 } 00182 00183 memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance)); 00184 00185 instance->reference.ptr = call_data; 00186 snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len); 00187 00188 call_data->proxy_instance.node = &threadsync_node->target->node; 00189 call_data->threadsync_node = threadsync_node; 00190 00191 call_data->arg1.root_oid = root_oid; 00192 call_data->arg2.root_oid_len = root_oid_len; 00193 call_synced_function(call_data, fn); 00194 00195 if (call_data->retval.err == SNMP_ERR_NOERROR) { 00196 instance->access = call_data->proxy_instance.access; 00197 instance->asn1_type = call_data->proxy_instance.asn1_type; 00198 instance->release_instance = threadsync_release_instance; 00199 instance->get_value = (call_data->proxy_instance.get_value != NULL) ? threadsync_get_value : NULL; 00200 instance->set_value = (call_data->proxy_instance.set_value != NULL) ? threadsync_set_value : NULL; 00201 instance->set_test = (call_data->proxy_instance.set_test != NULL) ? threadsync_set_test : NULL; 00202 snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len); 00203 } 00204 00205 return call_data->retval.err; 00206 } 00207 00208 snmp_err_t 00209 snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance) 00210 { 00211 return do_sync(root_oid, root_oid_len, instance, get_instance_synced); 00212 } 00213 00214 snmp_err_t 00215 snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance *instance) 00216 { 00217 return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced); 00218 } 00219 00220 /** Initializes thread synchronization instance */ 00221 void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn) 00222 { 00223 err_t err = sys_mutex_new(&instance->sem_usage_mutex); 00224 LWIP_ASSERT("Failed to set up mutex", err == ERR_OK); 00225 err = sys_sem_new(&instance->sem, 0); 00226 LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ 00227 LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK); 00228 instance->sync_fn = sync_fn; 00229 } 00230 00231 #endif /* LWIP_SNMP */
Generated on Tue Jul 12 2022 13:54:30 by
