SCOM Serial Communication Protocol  0.5.2
scom_filtering.c
Go to the documentation of this file.
1 
9 #define HAL_LOG_CHANNEL SCOM
10 #define HAL_LOG_SUBCHANNEL FILTERING
11 
12 #include "hal.h"
13 #include "scom.h"
14 #include "scom_filtering.h"
15 //#include "scom_log.h"
16 #include <string.h>
17 
18 #ifndef SCOM_FILTERING_ACCESS_GUARD_TIMEOUT
19 #define SCOM_FILTERING_ACCESS_GUARD_TIMEOUT 5000
20 #endif
21 
22 #ifndef SCOM_FILTER_PROC_PERIOD
23 #define SCOM_FILTER_PROC_PERIOD 40
24 #endif
25 
26 // -----------------------------------------------------------------------------
27 // SCOM_FilteringFrameReceptionHandler
28 // -----------------------------------------------------------------------------
30 {
31 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
32  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
33  // give a semaphore
34  OSCNTSEM_Give(scom->filters.dataReady);
35  HAL_LOG_DEBUG("SCOM_FilteringFrameReceptionHandler: Semaphore give.");
36  return false; //return false for add frame to queue
37  }
38 #endif
39  return true; //error occurred return true for frame delete
40 } /* SCOM_FilteringFrameReceptionHandler */
41 
42 // -----------------------------------------------------------------------------
43 // SCOM_FilterProc
44 // -----------------------------------------------------------------------------
46 {
47 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
48  LLSTItem item;
49  SCOMFilter filter;
50  SCOMFrame* frame;
51 
52  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
53  //if some data to filter
54  if(OSCNTSEM_Take(scom->filters.dataReady, 0) == 0) {
55  HAL_LOG_DEBUG("SCOM_FilterProc: Processing filter frame.");
56 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
57  // before we proceed, acquire mutex guarding access to the SCOM object
58  HAL_ASSERT_AND_EXECUTE((0 == OSMUTEX_Take(scom->accessGuard, SCOM_FILTERING_ACCESS_GUARD_TIMEOUT))) {
59 #endif
60  //get frame for filtering
61  frame = SCOM_GetReceivedFrame(scom);
62  HAL_ASSERT_AND_EXECUTE(NULL != frame){
63  // get first item on the filter list
64  item = LLST_GetFirstItem(&scom->filters.list);
65  while (item) {
66  // item data is a pointer to filter
67  filter = (SCOMFilter)item->data;
68  // check filter integrity
69  if ((filter) && (filter->filter_match_function)) {
70  // run the filter
71  if (filter->filter_match_function(scom, filter, frame)) {
72  // filter matched!
73  SCOM_UnlockFrame(scom, frame);
74 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
75  // release mutex guarding access to the SCOM object
76  OSMUTEX_Give(scom->accessGuard);
77 #endif
78  return;
79  }
80  }
81  // move to the next item
82  item = LLST_GetNextItem(item);
83  }
84  HAL_LOG_DEBUG("SCOM_FilterProc: Deleting frame. Failed in matching frame, type: %" PRIu8"", frame->type);
85  SCOM_UnlockFrame(scom, frame);
86  }
87 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
88  // release mutex guarding access to the SCOM object
89  OSMUTEX_Give(scom->accessGuard);
90  }
91 #endif
92  }
93  }
94 #endif
95 } /* SCOM_FilterProc */
96 
97 
98 // -----------------------------------------------------------------------------
99 // SCOM_InsertFilter
100 // -----------------------------------------------------------------------------
102 {
104 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
105  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
106  HAL_ASSERT_AND_EXECUTE(NULL != filter) {
107 
108 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
109  // before we proceed, acquire mutex guarding access to the SCOM object
110  HAL_ASSERT_AND_EXECUTE((0 == OSMUTEX_Take(scom->accessGuard, SCOM_FILTERING_ACCESS_GUARD_TIMEOUT))) {
111 #endif
112 
113  if (HALRESULT_OK == LLST_AddItem(&scom->filters.list, filter, NULL)) {
114  result = SCOM_RESULT_OK;
115  }
116 
117 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
118  // release mutex guarding access to the SCOM object
119  OSMUTEX_Give(scom->accessGuard);
120  }
121 #endif
122  }
123  }
124 #endif
125 
126  return result;
127 
128 } /* SCOM_InsertFilter */
129 
130 
131 // -----------------------------------------------------------------------------
132 // SCOM_RemoveFilter
133 // -----------------------------------------------------------------------------
135 {
136  SCOMResult result = SCOM_ERROR;
137 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
138  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
139  HAL_ASSERT_AND_EXECUTE(NULL != filter) {
140 
141 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
142  // before we proceed, acquire mutex guarding access to the SCOM object
143  HAL_ASSERT_AND_EXECUTE((0 == OSMUTEX_Take(scom->accessGuard, SCOM_FILTERING_ACCESS_GUARD_TIMEOUT))) {
144 #endif
145 
146  LLSTItem item = LLST_GetItemByData(&scom->filters.list, filter);
147  if (item) {
148  LLST_UnlinkItem(&scom->filters.list, item);
149  result = SCOM_RESULT_OK;
150  }
151 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
152  // release mutex guarding access to the SCOM object
153  OSMUTEX_Give(scom->accessGuard);
154  }
155 #endif
156  }
157  }
158 #endif
159  return result;
160 
161 } /* SCOM_RemoveFilter */
162 
163 
164 // -----------------------------------------------------------------------------
165 // SCOM_InitFiltering
166 // -----------------------------------------------------------------------------
168 {
169  SCOMResult result = SCOM_ERROR;
170 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
171 
172  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
173 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
174  // before we proceed, acquire mutex guarding access to the SCOM object
175  HAL_ASSERT_AND_EXECUTE((0 == OSMUTEX_Take(scom->accessGuard, SCOM_FILTERING_ACCESS_GUARD_TIMEOUT))) {
176 #endif
177  // clear the memory space used for filters
178  memset(scom->filters.pool, 0x00, sizeof(LLSTItemDesc) * SCOM_MAX_FRAME_FILTERS);
179  // initialize link list
180  LLST_Init(&scom->filters.list, scom->filters.pool, SCOM_MAX_FRAME_FILTERS);
181  //
182  if (scom->frameBuffer->rxFrameQueue.size > 0) {
183  scom->filters.dataReady = OSCNTSEM_Create(0, scom->frameBuffer->rxFrameQueue.size);
184  } else {
185  scom->filters.dataReady = OSCNTSEM_Create(0, 255);
186  }
187 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
188  // release mutex guarding access to the SCOM object
189  OSMUTEX_Give(scom->accessGuard);
190  }
191 #endif
192  // Set filtering reception handler
194 
195  result = SCOM_RESULT_OK;
196  }
197 #endif
198  return result;
199 
200 } /* SCOM_InitFiltering */
201 
202 
203 // -----------------------------------------------------------------------------
204 // SCOM_DeinitFiltering
205 // -----------------------------------------------------------------------------
207 {
208  SCOMResult result = SCOM_ERROR;
209 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
210  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
211 
212 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
213  // before we proceed, acquire mutex guarding access to the SCOM object
214  HAL_ASSERT_AND_EXECUTE((0 == OSMUTEX_Take(scom->accessGuard, SCOM_FILTERING_ACCESS_GUARD_TIMEOUT))) {
215 #endif
216 
217  if (scom->filters.dataReady) {
218  OSCNTSEM_Destroy(scom->filters.dataReady);
219  scom->filters.dataReady = NULL;
220  }
221  result = SCOM_RESULT_OK;
222 
223 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
224  // release mutex guarding access to the SCOM object
225  OSMUTEX_Give(scom->accessGuard);
226  }
227 #endif
228  }
229 #endif
230  return result;
231 } /* SCOM_DeinitFiltering */
232 
233 
234 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
235 
236 // -----------------------------------------------------------------------------
237 // SCOM_FilterThread
238 // -----------------------------------------------------------------------------
239 static int SCOM_FilterThread(void* param)
240 {
241  HAL_ASSERT_AND_EXECUTE(NULL != param) {
242  SCOMDataLink scom = (SCOMDataLink)param;
243 
244  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
245 
246  while (OSTASK_IsAlive()) {
247  SCOM_FilterProc(scom);
248  OS_Sleep(SCOM_FILTER_PROC_PERIOD);
249  }
250  }
251  }
252  return 0;
253 } /* SCOM_ProcThread */
254 
255 #endif
256 
257 
258 // -----------------------------------------------------------------------------
259 // SCOM_RunFilteringThread
260 // -----------------------------------------------------------------------------
262 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
263 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
264  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
265  // run the filtering thread
266  scom->filterTask = OSTASK_Create(SCOM_FilterThread, HAL_OSTASK_JOINABLE | HAL_OSTASK_MORTAL, HAL_OSTASK_PRIORITY_NORMAL, 0, scom);
267  HAL_ASSERT_AND_EXECUTE(OSTASK_IsValid(scom->filterTask)) {
268  return SCOM_RESULT_OK;
269  }
270  }
271 #endif
272 #endif
273  return SCOM_ERROR;
274 } /* SCOM_RunFilteringThread */
275 
276 // -----------------------------------------------------------------------------
277 // SCOM_StopFilteringThread
278 // -----------------------------------------------------------------------------
280 #if defined SCOM_MAX_FRAME_FILTERS && (SCOM_MAX_FRAME_FILTERS > 0)
281 #if defined HAL_ENABLE_OS && (HAL_ENABLE_OS == 1)
282  HAL_ASSERT_AND_EXECUTE(NULL != scom) {
283  // send the termination signal
284  OSTASK_Kill(scom->filterTask);
285  // wait for the thread to finish
286  if (!OSTASK_Join(scom->filterTask, 10000, NULL)) {
287  HAL_LOG_WARNING("Unable to stop SCOM filtering thread");
288  }
289  }
290 #endif
291 #endif
292 
293 } /* SCOM_StopFilteringThread */
Main API file.
SCOMFrameQueue rxFrameQueue
descriptor of the frame queue used for receiving
Definition: scom.h:67
SCOMResult SCOM_SetFrameReceptionHandlerFunc(SCOMDataLinkDesc *const scom, SCOMFrameReceptionHandler frameReceptionFunc)
Definition: scom.c:802
void SCOM_StopFilteringThread(SCOMDataLink scom)
SCOM version record.
Definition: scom.h:81
#define SCOM_FILTERING_ACCESS_GUARD_TIMEOUT
Packet filtering API.
struct SCOMFilterDesc * SCOMFilter
Utility type being a pointer to a SCOM frame filter descriptor.
bool SCOM_FilteringFrameReceptionHandler(SCOMDataLink scom, SCOMFrame *frame)
void SCOM_FilterProc(SCOMDataLink scom)
SCOMResult SCOM_RemoveFilter(SCOMDataLink scom, SCOMFilter filter)
SCOMDataLinkDesc * SCOMDataLink
Definition: scom.h:195
uint8_t type
frame type field
size_t size
Pool size (number of managed items)
SCOMResult SCOM_RunFilteringThread(SCOMDataLink scom)
SCOMResult
Definition: scom.h:211
Actual definition of the SCOM frame filter descriptor structure.
SCOMResult SCOM_InitFiltering(SCOMDataLink scom)
SCOMResult SCOM_DeinitFiltering(SCOMDataLink scom)
SCOMResult SCOM_InsertFilter(SCOMDataLink scom, SCOMFilter filter)
SCOMFilterMatchFunc filter_match_function
function that performs filter matching
void SCOM_UnlockFrame(SCOMDataLink scom, SCOMFrame *frame)
Definition: scom.c:1086
#define SCOM_FILTER_PROC_PERIOD
SCOMFrame * SCOM_GetReceivedFrame(SCOMDataLink scom)
Definition: scom.c:1065
#define SCOM_MAX_FRAME_FILTERS
Definition: doxygen.h:652