wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wolfevent.c Source File

wolfevent.c

00001 /* wolfevent.c
00002  *
00003  * Copyright (C) 2006-2020 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <wolfssl/wolfcrypt/settings.h>
00027 
00028 
00029 #ifdef HAVE_WOLF_EVENT
00030 
00031 #include <wolfssl/internal.h>
00032 #include <wolfssl/error-ssl.h>
00033 #include <wolfssl/wolfcrypt/error-crypt.h >
00034 
00035 #include <wolfssl/wolfcrypt/wolfevent.h>
00036 
00037 
00038 int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context)
00039 {
00040     if (event == NULL) {
00041         return BAD_FUNC_ARG;
00042     }
00043 
00044     if (event->state == WOLF_EVENT_STATE_PENDING) {
00045         WOLFSSL_MSG("Event already pending!");
00046         return BAD_COND_E;
00047     }
00048 
00049     XMEMSET(event, 0, sizeof(WOLF_EVENT));
00050     event->type = type;
00051     event->context = context;
00052 
00053     return 0;
00054 }
00055 
00056 int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags)
00057 {
00058     int ret = BAD_COND_E;
00059 
00060     /* Check hardware */
00061 #ifdef WOLFSSL_ASYNC_CRYPT
00062     if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST &&
00063         event->type <= WOLF_EVENT_TYPE_ASYNC_LAST)
00064     {
00065         ret = wolfAsync_EventPoll(event, flags);
00066     }
00067 #endif /* WOLFSSL_ASYNC_CRYPT */
00068 
00069     return ret;
00070 }
00071 
00072 int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue)
00073 {
00074     int ret = 0;
00075 
00076     if (queue == NULL) {
00077         return BAD_FUNC_ARG;
00078     }
00079 
00080     XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE));
00081 #ifndef SINGLE_THREADED
00082     ret = wc_InitMutex(&queue->lock);
00083 #endif
00084     return ret;
00085 }
00086 
00087 
00088 int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00089 {
00090     int ret;
00091 
00092     if (queue == NULL || event == NULL) {
00093         return BAD_FUNC_ARG;
00094     }
00095 
00096 #ifndef SINGLE_THREADED
00097     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00098         return ret;
00099     }
00100 #endif
00101 
00102     ret = wolfEventQueue_Add(queue, event);
00103 
00104 #ifndef SINGLE_THREADED
00105     wc_UnLockMutex(&queue->lock);
00106 #endif
00107 
00108     return ret;
00109 }
00110 
00111 int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event)
00112 {
00113     int ret = 0;
00114 
00115     if (queue == NULL || event == NULL) {
00116         return BAD_FUNC_ARG;
00117     }
00118 
00119 #ifndef SINGLE_THREADED
00120     /* In single threaded mode "event_queue.lock" doesn't exist */
00121     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00122         return ret;
00123     }
00124 #endif
00125 
00126     /* Pop first item off queue */
00127     *event = queue->head;
00128     ret = wolfEventQueue_Remove(queue, *event);
00129 
00130 #ifndef SINGLE_THREADED
00131     wc_UnLockMutex(&queue->lock);
00132 #endif
00133 
00134     return ret;
00135 }
00136 
00137 /* assumes queue is locked by caller */
00138 int wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00139 {
00140     if (queue == NULL || event == NULL) {
00141         return BAD_FUNC_ARG;
00142     }
00143 
00144     event->next = NULL; /* added to end */
00145     event->prev = NULL;
00146     if (queue->tail == NULL)  {
00147         queue->head = event;
00148     }
00149     else {
00150         queue->tail->next = event;
00151         event->prev = queue->tail;
00152     }
00153     queue->tail = event;      /* add to the end either way */
00154     queue->count++;
00155 
00156     return 0;
00157 }
00158 
00159 /* assumes queue is locked by caller */
00160 int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
00161 {
00162     int ret = 0;
00163 
00164     if (queue == NULL || event == NULL) {
00165         return BAD_FUNC_ARG;
00166     }
00167 
00168     if (event == queue->head && event == queue->tail) {
00169         queue->head = NULL;
00170         queue->tail = NULL;
00171     }
00172     else if (event == queue->head) {
00173         queue->head = event->next;
00174         queue->head->prev = NULL;
00175     }
00176     else if (event == queue->tail) {
00177         queue->tail = event->prev;
00178         queue->tail->next = NULL;
00179     }
00180     else {
00181         WOLF_EVENT* next = event->next;
00182         WOLF_EVENT* prev = event->prev;
00183         next->prev = prev;
00184         prev->next = next;
00185     }
00186     queue->count--;
00187 
00188     return ret;
00189 }
00190 
00191 int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter,
00192     WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount)
00193 {
00194     WOLF_EVENT* event;
00195     int ret = 0, count = 0;
00196 
00197     if (queue == NULL) {
00198         return BAD_FUNC_ARG;
00199     }
00200 
00201 #ifndef SINGLE_THREADED
00202     /* In single threaded mode "event_queue.lock" doesn't exist */
00203     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00204         return ret;
00205     }
00206 #endif
00207 
00208     /* itterate event queue */
00209     for (event = queue->head; event != NULL; event = event->next)
00210     {
00211         /* optional filter based on context */
00212         if (context_filter == NULL || event->context == context_filter) {
00213 
00214             /* poll event */
00215             ret = wolfEvent_Poll(event, flags);
00216             if (ret < 0) break; /* exit for */
00217 
00218             /* If event is done then process */
00219             if (event->state == WOLF_EVENT_STATE_DONE) {
00220                 /* remove from queue */
00221                 ret = wolfEventQueue_Remove(queue, event);
00222                 if (ret < 0) break; /* exit for */
00223 
00224                 /* return pointer in 'events' arg */
00225                 if (events) {
00226                     events[count] = event; /* return pointer */
00227                 }
00228                 count++;
00229 
00230                 /* check to make sure our event list isn't full */
00231                 if (events && count >= maxEvents) {
00232                     break; /* exit for */
00233                 }
00234             }
00235         }
00236     }
00237 
00238 #ifndef SINGLE_THREADED
00239     wc_UnLockMutex(&queue->lock);
00240 #endif
00241 
00242     /* return number of properly populated events */
00243     if (eventCount) {
00244         *eventCount = count;
00245     }
00246 
00247     return ret;
00248 }
00249 
00250 int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue)
00251 {
00252     int ret;
00253 
00254     if (queue == NULL) {
00255         return BAD_FUNC_ARG;
00256     }
00257 
00258 #ifndef SINGLE_THREADED
00259     /* In single threaded mode "event_queue.lock" doesn't exist */
00260     if ((ret = wc_LockMutex(&queue->lock)) != 0) {
00261         return ret;
00262     }
00263 #endif
00264 
00265     ret = queue->count;
00266 
00267 #ifndef SINGLE_THREADED
00268     wc_UnLockMutex(&queue->lock);
00269 #endif
00270 
00271     return ret;
00272 }
00273 
00274 void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue)
00275 {
00276     if (queue) {
00277     #ifndef SINGLE_THREADED
00278         wc_FreeMutex(&queue->lock);
00279     #endif
00280     }
00281 }
00282 
00283 #endif /* HAVE_WOLF_EVENT */
00284