STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
snmp_threadsync.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25  * OF SUCH DAMAGE.
26  *
27  * Author: Dirk Ziegelmeier <dziegel@gmx.de>
28  */
29 
30 #include "lwip/apps/snmp_opts.h"
31 
32 #if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */
33 
35 #include "lwip/apps/snmp_core.h"
36 #include "lwip/sys.h"
37 #include <string.h>
38 
39 static void
40 call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn)
41 {
42  sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex);
43  call_data->threadsync_node->instance->sync_fn(fn, call_data);
44  sys_sem_wait(&call_data->threadsync_node->instance->sem);
45  sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex);
46 }
47 
48 static void
49 threadsync_get_value_synced(void *ctx)
50 {
51  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
52 
53  call_data->retval.u16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
54 
55  sys_sem_signal(&call_data->threadsync_node->instance->sem);
56 }
57 static u16_t
58 threadsync_get_value(struct snmp_node_instance* instance, void* value)
59 {
60  struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
61 
62  call_data->arg1.value = value;
63  call_synced_function(call_data, threadsync_get_value_synced);
64 
65  return call_data->retval.u16;
66 }
67 
68 static void
69 threadsync_set_test_synced(void *ctx)
70 {
71  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
72 
73  call_data->retval.u8 = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
74 
75  sys_sem_signal(&call_data->threadsync_node->instance->sem);
76 }
77 static snmp_err_t
78 threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value)
79 {
80  struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
81 
82  call_data->arg1.value = value;
83  call_data->arg2.len = len;
84  call_synced_function(call_data, threadsync_set_test_synced);
85 
86  return call_data->retval.u8;
87 }
88 
89 static void
90 threadsync_set_value_synced(void *ctx)
91 {
92  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
93 
94  call_data->retval.u8 = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
95 
96  sys_sem_signal(&call_data->threadsync_node->instance->sem);
97 }
98 static snmp_err_t
99 threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
100 {
101  struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
102 
103  call_data->arg1.value = value;
104  call_data->arg2.len = len;
105  call_synced_function(call_data, threadsync_set_value_synced);
106 
107  return call_data->retval.u8;
108 }
109 
110 static void
111 threadsync_release_instance_synced(void* ctx)
112 {
113  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
114 
115  call_data->proxy_instance.release_instance(&call_data->proxy_instance);
116 
117  sys_sem_signal(&call_data->threadsync_node->instance->sem);
118 }
119 static void
120 threadsync_release_instance(struct snmp_node_instance *instance)
121 {
122  struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
123 
124  if(call_data->proxy_instance.release_instance != NULL) {
125  call_synced_function(call_data, threadsync_release_instance_synced);
126  }
127 }
128 
129 static void
130 get_instance_synced(void* ctx)
131 {
132  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
133  const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)call_data->proxy_instance.node;
134 
135  call_data->retval.u8 = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
136 
137  sys_sem_signal(&call_data->threadsync_node->instance->sem);
138 }
139 
140 static void
141 get_next_instance_synced(void* ctx)
142 {
143  struct threadsync_data *call_data = (struct threadsync_data*)ctx;
144  const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)call_data->proxy_instance.node;
145 
146  call_data->retval.u8 = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
147 
148  sys_sem_signal(&call_data->threadsync_node->instance->sem);
149 }
150 
151 static snmp_err_t
152 do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn)
153 {
154  const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)instance->node;
155  struct threadsync_data *call_data = &threadsync_node->instance->data;
156 
157  if(threadsync_node->node.node.oid != threadsync_node->target->node.oid) {
158  LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID"));
159  return SNMP_ERR_NOSUCHINSTANCE;
160  }
161 
162  memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance));
163 
164  instance->reference.ptr = call_data;
165  snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len);
166 
167  call_data->proxy_instance.node = &threadsync_node->target->node;
168  call_data->threadsync_node = threadsync_node;
169 
170  call_data->arg1.root_oid = root_oid;
171  call_data->arg2.root_oid_len = root_oid_len;
172  call_synced_function(call_data, fn);
173 
174  if(call_data->retval.u8 == SNMP_ERR_NOERROR) {
175  instance->access = call_data->proxy_instance.access;
176  instance->asn1_type = call_data->proxy_instance.asn1_type;
177  instance->release_instance = threadsync_release_instance;
178  instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL;
179  instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL;
180  instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL;
181  snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len);
182  }
183 
184  return call_data->retval.u8;
185 }
186 
187 snmp_err_t
188 snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
189 {
190  return do_sync(root_oid, root_oid_len, instance, get_instance_synced);
191 }
192 
193 snmp_err_t
194 snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
195 {
196  return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced);
197 }
198 
200 void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn)
201 {
202  err_t err = sys_mutex_new(&instance->sem_usage_mutex);
203  LWIP_ASSERT("Failed to set up mutex", err == ERR_OK);
204  err = sys_sem_new(&instance->sem, 0);
205  LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK);
206  instance->sync_fn = sync_fn;
207 }
208 
209 #endif /* LWIP_SNMP */
err_t sys_mutex_new(sys_mutex_t *mutex)
Definition: sys_arch.c:339
void sys_mutex_unlock(sys_mutex_t *mutex)
Definition: sys_arch.c:377
void sys_mutex_lock(sys_mutex_t *mutex)
Definition: sys_arch.c:370
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:221
#define sys_sem_wait(sem)
Definition: sys.h:157
#define NULL
Definition: usbd_def.h:53
unsigned long u32_t
Definition: cc.h:42
#define ERR_OK
Definition: err.h:52
s8_t err_t
Definition: err.h:47
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:70
#define SNMP_DEBUG
Definition: snmp_opts.h:189
unsigned char u8_t
Definition: cc.h:38
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:296
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:113
unsigned short u16_t
Definition: cc.h:40