Sebastián Pastor / EtheriosCloudConnector
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers connector_static_buffer.h Source File

connector_static_buffer.h

00001 /*
00002  * Copyright (c) 2013 Digi International Inc.,
00003  * All rights not expressly granted are reserved.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
00007  * You can obtain one at http://mozilla.org/MPL/2.0/.
00008  *
00009  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
00010  * =======================================================================
00011  */
00012 
00013 /* Example of adding a static buffer (single structure) or static buffer array named my_data
00014  *  
00015  * In os_intf.h: 
00016  * 1. Add to connector_static_buffer_id_t:
00017  *      named_buffer_id(my_data)
00018  * - Single buffers share a msg_facility map, and their id's should go up from the bottom (28, 27, etc.)
00019  * - All arrays should be before single buffers
00020  *  
00021  * In this file:
00022  * 2. - If there is a type, add:
00023  *         typedef my_buffer_type_t named_buffer_type(my_data);
00024  *  
00025  *    - If you know size in bytes instead (for example 100 bytes), add:
00026  *         define_sized_buffer_type(my_data, 100);
00027  *  
00028  * For a single static buffer:
00029  * 3. Add to connector_static_mem: 
00030  *      named_buffer_define(my_data);
00031  *  
00032  * 4. Add to malloc_static_data(): 
00033  *      case named_buffer_id(my_data):
00034  *         malloc_named_static_buffer(my_data, size, ptr, status);
00035  *         break;
00036  *  
00037  * 5. Add to free_static_data(): 
00038  *      case named_buffer_id(my_data):
00039  *           free_named_static_buffer(my_data);
00040  *           break;
00041  *  
00042  * For an array of 20 elements (must be <= 32): 
00043  * 3. Add: 
00044  *      #define my_data_buffer_cnt 20
00045  *  
00046  * 4. Add to connector_static_mem: 
00047  *      named_buffer_array_define(my_data);
00048  *      named_buffer_map_define(my_data);
00049  *
00050  * 5. Add to malloc_static_data(): 
00051  *      case named_buffer_id(my_data):
00052  *         malloc_named_array_element(my_data, size, ptr, status);
00053  *         break;
00054  * 
00055  * 6. Add to free_static_data(): 
00056  *      case named_buffer_id(my_data):
00057  *           free_named_array_element(my_data, ptr);
00058  *           break;
00059  * 
00060  */
00061 
00062 
00063 #define named_buffer_type(name)         name##_static_buffer_t
00064 #define named_buffer_decl(name)         name
00065 #define named_buffer_map_decl(name)     name##_map
00066 #define named_buffer_cnt(name)          name##_buffer_cnt
00067 #define named_buffer_define(name)       named_buffer_type(name) named_buffer_decl(name)
00068 #define named_buffer_array_define(name) named_buffer_define(name)[named_buffer_cnt(name)]
00069 #define named_buffer_map_define(name)   uint32_t named_buffer_map_decl(name)
00070 
00071 #define named_buffer_storage(name)      connector_static_mem.named_buffer_decl(name)
00072 #define named_buffer_map(name)          connector_static_mem.named_buffer_map_decl(name)
00073 
00074 #define define_sized_buffer_type(name, size) typedef struct { char field[(size)]; } named_buffer_type(name)
00075 
00076 /*** Define types used by static memory system ***/
00077 
00078 #if defined CONNECTOR_TRANSPORT_TCP
00079 
00080 #if (defined CONNECTOR_DATA_SERVICE) || (defined CONNECTOR_FILE_SYSTEM) || defined (CONNECTOR_RCI_SERVICE)
00081 #ifndef CONNECTOR_MSG_MAX_TRANSACTION
00082 #define CONNECTOR_MSG_MAX_TRANSACTION   1
00083 #endif
00084 
00085 #if CONNECTOR_MSG_MAX_TRANSACTION > 32
00086 #error "CONNECTOR_MSG_MAX_TRANSACTION must be <= 32"
00087 #endif
00088 
00089 #define CONNECTOR_MSG_SERVICE
00090 
00091 #if defined CONNECTOR_RCI_SERVICE
00092 #define RCI_SERVICE_CNT     1
00093 #define DATA_BLOCKS_PER_MSG 2
00094 #else
00095 #define RCI_SERVICE_CNT     0
00096 #define DATA_BLOCKS_PER_MSG 1
00097 #endif
00098 
00099 #if defined CONNECTOR_DATA_SERVICE
00100 #define DATA_SERVICE_CNT 1
00101 #else
00102 #define DATA_SERVICE_CNT 0
00103 #endif
00104 
00105 #if defined CONNECTOR_FILE_SYSTEM
00106 #define FILE_SYSTEM_CNT 1
00107 #else
00108 #define FILE_SYSTEM_CNT 0
00109 #endif
00110 
00111 #define msg_facility_buffer_cnt (DATA_SERVICE_CNT + FILE_SYSTEM_CNT + RCI_SERVICE_CNT)
00112 
00113 #define msg_session_buffer_cnt  (CONNECTOR_MSG_MAX_TRANSACTION * msg_facility_buffer_cnt)
00114 #define msg_service_buffer_cnt  msg_session_buffer_cnt
00115 
00116 #if defined CONNECTOR_DATA_SERVICE
00117 
00118 #ifndef CONNECTOR_NO_MALLOC_MAX_SEND_SESSIONS
00119 #define CONNECTOR_NO_MALLOC_MAX_SEND_SESSIONS   1
00120 #endif
00121 
00122 #define msg_session_client_buffer_cnt  CONNECTOR_NO_MALLOC_MAX_SEND_SESSIONS
00123 #define put_request_buffer_cnt      msg_session_client_buffer_cnt
00124 typedef data_service_context_t      named_buffer_type(put_request);
00125 
00126 #if defined CONNECTOR_DATA_POINTS
00127 #define data_point_block_buffer_cnt msg_session_client_buffer_cnt
00128 typedef data_point_info_t           named_buffer_type(data_point_block);
00129 #endif
00130 #endif
00131 
00132 typedef struct
00133 {
00134     connector_facility_t fc;
00135     connector_msg_data_t msg;
00136 
00137 } named_buffer_type(msg_facility);
00138 
00139 typedef union
00140 {
00141 #if defined CONNECTOR_DATA_SERVICE
00142     data_service_context_t ds;
00143 #endif
00144 #if defined CONNECTOR_FILE_SYSTEM
00145     fs_context_t  fs;
00146 #endif
00147 
00148 #if defined CONNECTOR_RCI_SERVICE
00149     rci_service_data_t     rci;
00150 #endif
00151 } named_buffer_type(msg_service);
00152 
00153 #if defined CONNECTOR_COMPRESSION
00154 #define MSG_SEND_SIZE   0
00155 #else
00156 #define MSG_SEND_SIZE   MSG_MAX_SEND_PACKET_SIZE
00157 #endif
00158 #define MSG_BLOCK_SIZE          (sizeof(msg_data_block_t) + sizeof(msg_service_data_t))
00159 #define MSG_SESSION_CLIENT_SIZE (sizeof(msg_session_t) + MSG_BLOCK_SIZE + MSG_SEND_SIZE)
00160 #define MSG_SESSION_SIZE        (sizeof(msg_session_t) + DATA_BLOCKS_PER_MSG * MSG_BLOCK_SIZE + MSG_SEND_SIZE)
00161 
00162 define_sized_buffer_type(msg_session, MSG_SESSION_SIZE);
00163 define_sized_buffer_type(msg_session_client, MSG_SESSION_CLIENT_SIZE);
00164 #endif
00165 
00166 typedef struct
00167 {
00168     connector_facility_t fc;
00169     connector_cc_data_t  cc;
00170 
00171 } named_buffer_type(cc_facility);
00172 
00173 #if defined CONNECTOR_FIRMWARE_SERVICE || defined CONNECTOR_RCI_SERVICE
00174 typedef struct
00175 {
00176     connector_facility_t fc;
00177     connector_firmware_data_t  fw;
00178 
00179 } named_buffer_type(fw_facility);
00180 #endif
00181 #endif /* CONNECTOR_TRANSPORT_TCP */
00182 
00183 #if (defined CONNECTOR_SHORT_MESSAGE)
00184 
00185 #ifndef CONNECTOR_SM_MAX_RX_SEGMENTS
00186 #define CONNECTOR_SM_MAX_RX_SEGMENTS   1
00187 #endif
00188 
00189 #ifndef CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS
00190 #define CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS   1
00191 #endif
00192 
00193 #define CONNECTOR_MAX_SM_SEGMENTS   (CONNECTOR_SM_MAX_RX_SEGMENTS + CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS)
00194 
00195 #ifndef CONNECTOR_SM_MAX_SESSIONS
00196 #define CONNECTOR_SM_MAX_SESSIONS   4
00197 #endif
00198 
00199 #if CONNECTOR_SM_MAX_SESSIONS > 32
00200 #error "CONNECTOR_SM_MAX_SESSIONS must be <= 32"
00201 #endif
00202 
00203 #if defined (CONNECTOR_TRANSPORT_UDP) && defined (CONNECTOR_TRANSPORT_SMS)
00204 #define sm_session_buffer_cnt   (4 * CONNECTOR_SM_MAX_SESSIONS)
00205 #else
00206 #define sm_session_buffer_cnt   (2 * CONNECTOR_SM_MAX_SESSIONS)
00207 #endif
00208 
00209 #define sm_packet_buffer_cnt        sm_session_buffer_cnt
00210 #define sm_data_block_buffer_cnt    sm_session_buffer_cnt
00211 
00212 #if defined CONNECTOR_TRANSPORT_UDP 
00213 #define SM_MAX_MTU  SM_PACKET_SIZE_UDP
00214 #else
00215 #define SM_MAX_MTU  SM_PACKET_SIZE_SMS_ENCODED
00216 #endif
00217 
00218 typedef connector_sm_session_t named_buffer_type(sm_session);
00219 
00220 define_sized_buffer_type(sm_packet, 2 * SM_MAX_MTU);
00221 define_sized_buffer_type(sm_data_block, CONNECTOR_MAX_SM_SEGMENTS * SM_MAX_MTU);
00222 
00223 #endif
00224 
00225 typedef connector_data_t named_buffer_type(connector_data);
00226 
00227 
00228 /*** Declare static memory structure ***/
00229 static struct
00230 {
00231     named_buffer_define(connector_data);
00232     named_buffer_map_define(msg_facility);
00233 
00234 #if defined CONNECTOR_TRANSPORT_TCP
00235     named_buffer_define(cc_facility);
00236 
00237 #if defined CONNECTOR_FIRMWARE_SERVICE || defined CONNECTOR_RCI_SERVICE
00238     named_buffer_define(fw_facility);
00239 #endif
00240 
00241 #if defined CONNECTOR_MSG_SERVICE
00242     named_buffer_array_define(msg_facility);
00243     named_buffer_array_define(msg_session);
00244     named_buffer_array_define(msg_service);
00245 
00246     named_buffer_map_define(msg_session);
00247     named_buffer_map_define(msg_service);
00248 #endif
00249 
00250 #if defined CONNECTOR_DATA_SERVICE
00251     named_buffer_array_define(msg_session_client);
00252     named_buffer_array_define(put_request);
00253     named_buffer_map_define(msg_session_client);
00254     named_buffer_map_define(put_request);
00255 #if defined CONNECTOR_DATA_POINTS
00256     named_buffer_array_define(data_point_block);
00257     named_buffer_map_define(data_point_block);
00258 #endif
00259 #endif
00260 #endif
00261 
00262 #if defined CONNECTOR_TRANSPORT_UDP || defined CONNECTOR_TRANSPORT_SMS
00263     named_buffer_array_define(sm_session);
00264     named_buffer_array_define(sm_packet);
00265     named_buffer_array_define(sm_data_block);
00266 
00267     named_buffer_map_define(sm_session);
00268     named_buffer_map_define(sm_packet);
00269     named_buffer_map_define(sm_data_block);
00270 #endif
00271 
00272 } connector_static_mem;
00273 
00274 /*** Static memory operations ***/
00275 
00276 #define static_buffer_release(pmap, idx) (*(pmap) &= (~(1 << (idx))))
00277 
00278 static int static_buffer_reserve(uint32_t * const pmap, uint32_t const idx)
00279 {
00280     int result = -1;
00281 
00282     if ((*pmap & (1 << idx)) == 0)
00283     {
00284         *pmap |= 1 << idx;
00285         result = idx;
00286     }
00287     return result;
00288 }
00289 
00290 static int static_buffer_get_avail(uint32_t * const pmap, int max_cnt)
00291 {
00292     int idx = -1;
00293     int i;
00294 
00295     for (i = 0; i < max_cnt; i++)
00296     {
00297         idx = static_buffer_reserve(pmap, i);
00298         if (idx >= 0)
00299             break;
00300     }
00301     return idx;
00302 }
00303 
00304 #define static_buffer_malloc(pmap, name) static_buffer_reserve(pmap, named_buffer_id(name)) >= 0 ? &named_buffer_storage(name) : NULL
00305 #define static_buffer_free(pmap, name) static_buffer_release(pmap, named_buffer_id(name))
00306 
00307 #define free_named_array_element(name, ptr) \
00308 {   \
00309     int idx = ((named_buffer_type(name) *) ptr - (named_buffer_type(name) *) &named_buffer_storage(name)[0]); \
00310     ASSERT(idx >= 0 && idx < named_buffer_cnt(name)); \
00311     static_buffer_release(&named_buffer_map(name), idx); \
00312 }
00313 
00314 #define malloc_named_static_buffer(name, size, ptr, status) \
00315 { \
00316     ASSERT(size == sizeof(named_buffer_type(name))); \
00317     *ptr = static_buffer_malloc(&named_buffer_map(msg_facility), name); \
00318     status = *ptr != NULL ? connector_working : connector_pending; \
00319 }
00320 
00321 
00322 #define free_named_static_buffer(name) static_buffer_free(&named_buffer_map(msg_facility), name)
00323 
00324 #define malloc_named_array_element(name, size, ptr, status) \
00325 {   \
00326     int idx; \
00327     ASSERT(size <= sizeof(named_buffer_type(name))); \
00328     idx = static_buffer_get_avail(&named_buffer_map(name), named_buffer_cnt(name)); \
00329     *ptr = idx >= 0 ? &named_buffer_storage(name)[idx] : NULL; \
00330     status = *ptr != NULL ? connector_working : connector_pending; \
00331 }
00332 
00333 static connector_status_t malloc_static_data(connector_data_t * const connector_ptr, size_t const size, connector_static_buffer_id_t const buffer_id, void ** const ptr)
00334 {
00335     connector_status_t status = connector_working;
00336 
00337     UNUSED_PARAMETER(connector_ptr);
00338     UNUSED_PARAMETER(size);
00339 
00340     if (buffer_id != named_buffer_id(connector_data))
00341     {
00342         ASSERT(connector_ptr == &named_buffer_storage(connector_data));
00343     }
00344 
00345     switch(buffer_id)
00346     {
00347     case named_buffer_id(connector_data):
00348         malloc_named_static_buffer(connector_data, size, ptr, status);
00349         break;
00350 
00351 #if defined CONNECTOR_TRANSPORT_TCP
00352     case named_buffer_id(cc_facility):
00353         malloc_named_static_buffer(cc_facility, size, ptr, status);
00354         break;
00355 
00356 #if defined CONNECTOR_FIRMWARE_SERVICE || defined CONNECTOR_RCI_SERVICE
00357     case named_buffer_id(fw_facility):
00358         malloc_named_static_buffer(fw_facility, size, ptr, status);
00359         break;
00360 #endif
00361 
00362 #if defined CONNECTOR_MSG_SERVICE
00363     case named_buffer_id(msg_facility):
00364         malloc_named_array_element(msg_facility, size, ptr, status);
00365         break;
00366 
00367     case named_buffer_id(msg_session):
00368         malloc_named_array_element(msg_session, size, ptr, status);
00369         break;
00370 
00371     case named_buffer_id(msg_service):
00372         malloc_named_array_element(msg_service, size, ptr, status);
00373         break;
00374 
00375 #if defined CONNECTOR_DATA_SERVICE
00376     case named_buffer_id(msg_session_client):
00377         malloc_named_array_element(msg_session_client, size, ptr, status);
00378         break;
00379 
00380     case named_buffer_id(put_request):
00381         malloc_named_array_element(put_request, size, ptr, status);
00382         break;
00383 
00384 #if defined CONNECTOR_DATA_POINTS
00385     case named_buffer_id(data_point_block):
00386         malloc_named_array_element(data_point_block, size, ptr, status);
00387         break;
00388 #endif
00389 #endif
00390 #endif
00391 #endif
00392 
00393 #if defined CONNECTOR_TRANSPORT_UDP || defined CONNECTOR_TRANSPORT_SMS
00394     case named_buffer_id(sm_session):
00395         malloc_named_array_element(sm_session, size, ptr, status);
00396         break;
00397 
00398     case named_buffer_id(sm_packet):
00399         malloc_named_array_element(sm_packet, size, ptr, status);
00400         break;
00401 
00402     case named_buffer_id(sm_data_block):
00403         malloc_named_array_element(sm_data_block, size, ptr, status);
00404         break;
00405 #endif
00406 
00407     default:
00408         ASSERT(connector_false);
00409         *ptr = NULL;
00410         break;
00411     }
00412     return status;
00413 }
00414 
00415 void free_static_data(connector_data_t * const connector_ptr, connector_static_buffer_id_t const buffer_id, void * const ptr)
00416 {
00417     UNUSED_PARAMETER(connector_ptr);
00418     UNUSED_PARAMETER(ptr);
00419     ASSERT(connector_ptr == &named_buffer_storage(connector_data));
00420 
00421     switch(buffer_id)
00422     {
00423     case named_buffer_id(connector_data):
00424         free_named_static_buffer(connector_data);
00425         break;
00426 
00427 #if defined CONNECTOR_TRANSPORT_TCP
00428     case named_buffer_id(cc_facility):
00429         free_named_static_buffer(cc_facility);
00430         break;
00431 
00432 #if defined CONNECTOR_FIRMWARE_SERVICE || defined CONNECTOR_RCI_SERVICE
00433     case named_buffer_id(fw_facility):
00434         free_named_static_buffer(fw_facility);
00435         break;
00436 #endif
00437 
00438 #if defined CONNECTOR_MSG_SERVICE
00439     case named_buffer_id(msg_facility):
00440         free_named_array_element(msg_facility, ptr);
00441         break;
00442 
00443     case named_buffer_id(msg_service):
00444         free_named_array_element(msg_service, ptr);
00445         break;
00446 
00447 #if defined CONNECTOR_DATA_SERVICE
00448     case named_buffer_id(put_request):
00449         free_named_array_element(put_request, ptr);
00450         break;
00451 
00452 #if defined CONNECTOR_DATA_POINTS
00453     case named_buffer_id(data_point_block):
00454         free_named_array_element(data_point_block, ptr);
00455         break;
00456 #endif
00457 #endif
00458 
00459     case named_buffer_id(msg_session):
00460         {
00461 #if defined CONNECTOR_DATA_SERVICE
00462             named_buffer_type(msg_session_client) * data_ptr = ptr;
00463 
00464             if ((data_ptr >= &named_buffer_storage(msg_session_client)[0]) &&
00465                 (data_ptr <= &named_buffer_storage(msg_session_client)[named_buffer_cnt(msg_session_client)]))
00466             {
00467                 free_named_array_element(msg_session_client, ptr);
00468             }
00469             else
00470 #endif
00471             free_named_array_element(msg_session, ptr);
00472         }
00473         break;
00474 #endif
00475 #endif
00476 
00477 #if defined CONNECTOR_TRANSPORT_UDP || defined CONNECTOR_TRANSPORT_SMS
00478     case named_buffer_id(sm_session):
00479         free_named_array_element(sm_session, ptr);
00480         break;
00481 
00482     case named_buffer_id(sm_packet):
00483         free_named_array_element(sm_packet, ptr);
00484         break;
00485 
00486     case named_buffer_id(sm_data_block):
00487         free_named_array_element(sm_data_block, ptr);
00488         break;
00489 #endif
00490 
00491     default:
00492         break;
00493     }
00494 }
00495