1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "btstack_memory.c" 39 40 41 /* 42 * btstack_memory.h 43 * 44 * @brief BTstack memory management via configurable memory pools 45 * 46 * @note code generated by tool/btstack_memory_generator.py 47 * @note returnes buffers are initialized with 0 48 * 49 */ 50 51 #include "btstack_memory.h" 52 #include "btstack_memory_pool.h" 53 54 #include <stdlib.h> 55 56 57 58 // MARK: hci_connection_t 59 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_HCI_CONNECTIONS) 60 #if defined(MAX_NO_HCI_CONNECTIONS) 61 #error "Deprecated MAX_NO_HCI_CONNECTIONS defined instead of MAX_NR_HCI_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_HCI_CONNECTIONS." 62 #else 63 #define MAX_NR_HCI_CONNECTIONS 0 64 #endif 65 #endif 66 67 #ifdef MAX_NR_HCI_CONNECTIONS 68 #if MAX_NR_HCI_CONNECTIONS > 0 69 static hci_connection_t hci_connection_storage[MAX_NR_HCI_CONNECTIONS]; 70 static btstack_memory_pool_t hci_connection_pool; 71 hci_connection_t * btstack_memory_hci_connection_get(void){ 72 void * buffer = btstack_memory_pool_get(&hci_connection_pool); 73 if (buffer){ 74 memset(buffer, 0, sizeof(hci_connection_t)); 75 } 76 return (hci_connection_t *) buffer; 77 } 78 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){ 79 btstack_memory_pool_free(&hci_connection_pool, hci_connection); 80 } 81 #else 82 hci_connection_t * btstack_memory_hci_connection_get(void){ 83 return NULL; 84 } 85 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){ 86 // silence compiler warning about unused parameter in a portable way 87 (void) hci_connection; 88 }; 89 #endif 90 #elif defined(HAVE_MALLOC) 91 hci_connection_t * btstack_memory_hci_connection_get(void){ 92 void * buffer = malloc(sizeof(hci_connection_t)); 93 if (buffer){ 94 memset(buffer, 0, sizeof(hci_connection_t)); 95 } 96 return (hci_connection_t *) buffer; 97 } 98 void btstack_memory_hci_connection_free(hci_connection_t *hci_connection){ 99 free(hci_connection); 100 } 101 #endif 102 103 104 105 // MARK: l2cap_service_t 106 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_L2CAP_SERVICES) 107 #if defined(MAX_NO_L2CAP_SERVICES) 108 #error "Deprecated MAX_NO_L2CAP_SERVICES defined instead of MAX_NR_L2CAP_SERVICES. Please update your btstack_config.h to use MAX_NR_L2CAP_SERVICES." 109 #else 110 #define MAX_NR_L2CAP_SERVICES 0 111 #endif 112 #endif 113 114 #ifdef MAX_NR_L2CAP_SERVICES 115 #if MAX_NR_L2CAP_SERVICES > 0 116 static l2cap_service_t l2cap_service_storage[MAX_NR_L2CAP_SERVICES]; 117 static btstack_memory_pool_t l2cap_service_pool; 118 l2cap_service_t * btstack_memory_l2cap_service_get(void){ 119 void * buffer = btstack_memory_pool_get(&l2cap_service_pool); 120 if (buffer){ 121 memset(buffer, 0, sizeof(l2cap_service_t)); 122 } 123 return (l2cap_service_t *) buffer; 124 } 125 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){ 126 btstack_memory_pool_free(&l2cap_service_pool, l2cap_service); 127 } 128 #else 129 l2cap_service_t * btstack_memory_l2cap_service_get(void){ 130 return NULL; 131 } 132 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){ 133 // silence compiler warning about unused parameter in a portable way 134 (void) l2cap_service; 135 }; 136 #endif 137 #elif defined(HAVE_MALLOC) 138 l2cap_service_t * btstack_memory_l2cap_service_get(void){ 139 void * buffer = malloc(sizeof(l2cap_service_t)); 140 if (buffer){ 141 memset(buffer, 0, sizeof(l2cap_service_t)); 142 } 143 return (l2cap_service_t *) buffer; 144 } 145 void btstack_memory_l2cap_service_free(l2cap_service_t *l2cap_service){ 146 free(l2cap_service); 147 } 148 #endif 149 150 151 // MARK: l2cap_channel_t 152 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_L2CAP_CHANNELS) 153 #if defined(MAX_NO_L2CAP_CHANNELS) 154 #error "Deprecated MAX_NO_L2CAP_CHANNELS defined instead of MAX_NR_L2CAP_CHANNELS. Please update your btstack_config.h to use MAX_NR_L2CAP_CHANNELS." 155 #else 156 #define MAX_NR_L2CAP_CHANNELS 0 157 #endif 158 #endif 159 160 #ifdef MAX_NR_L2CAP_CHANNELS 161 #if MAX_NR_L2CAP_CHANNELS > 0 162 static l2cap_channel_t l2cap_channel_storage[MAX_NR_L2CAP_CHANNELS]; 163 static btstack_memory_pool_t l2cap_channel_pool; 164 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){ 165 void * buffer = btstack_memory_pool_get(&l2cap_channel_pool); 166 if (buffer){ 167 memset(buffer, 0, sizeof(l2cap_channel_t)); 168 } 169 return (l2cap_channel_t *) buffer; 170 } 171 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){ 172 btstack_memory_pool_free(&l2cap_channel_pool, l2cap_channel); 173 } 174 #else 175 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){ 176 return NULL; 177 } 178 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){ 179 // silence compiler warning about unused parameter in a portable way 180 (void) l2cap_channel; 181 }; 182 #endif 183 #elif defined(HAVE_MALLOC) 184 l2cap_channel_t * btstack_memory_l2cap_channel_get(void){ 185 void * buffer = malloc(sizeof(l2cap_channel_t)); 186 if (buffer){ 187 memset(buffer, 0, sizeof(l2cap_channel_t)); 188 } 189 return (l2cap_channel_t *) buffer; 190 } 191 void btstack_memory_l2cap_channel_free(l2cap_channel_t *l2cap_channel){ 192 free(l2cap_channel); 193 } 194 #endif 195 196 197 198 // MARK: rfcomm_multiplexer_t 199 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_MULTIPLEXERS) 200 #if defined(MAX_NO_RFCOMM_MULTIPLEXERS) 201 #error "Deprecated MAX_NO_RFCOMM_MULTIPLEXERS defined instead of MAX_NR_RFCOMM_MULTIPLEXERS. Please update your btstack_config.h to use MAX_NR_RFCOMM_MULTIPLEXERS." 202 #else 203 #define MAX_NR_RFCOMM_MULTIPLEXERS 0 204 #endif 205 #endif 206 207 #ifdef MAX_NR_RFCOMM_MULTIPLEXERS 208 #if MAX_NR_RFCOMM_MULTIPLEXERS > 0 209 static rfcomm_multiplexer_t rfcomm_multiplexer_storage[MAX_NR_RFCOMM_MULTIPLEXERS]; 210 static btstack_memory_pool_t rfcomm_multiplexer_pool; 211 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){ 212 void * buffer = btstack_memory_pool_get(&rfcomm_multiplexer_pool); 213 if (buffer){ 214 memset(buffer, 0, sizeof(rfcomm_multiplexer_t)); 215 } 216 return (rfcomm_multiplexer_t *) buffer; 217 } 218 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){ 219 btstack_memory_pool_free(&rfcomm_multiplexer_pool, rfcomm_multiplexer); 220 } 221 #else 222 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){ 223 return NULL; 224 } 225 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){ 226 // silence compiler warning about unused parameter in a portable way 227 (void) rfcomm_multiplexer; 228 }; 229 #endif 230 #elif defined(HAVE_MALLOC) 231 rfcomm_multiplexer_t * btstack_memory_rfcomm_multiplexer_get(void){ 232 void * buffer = malloc(sizeof(rfcomm_multiplexer_t)); 233 if (buffer){ 234 memset(buffer, 0, sizeof(rfcomm_multiplexer_t)); 235 } 236 return (rfcomm_multiplexer_t *) buffer; 237 } 238 void btstack_memory_rfcomm_multiplexer_free(rfcomm_multiplexer_t *rfcomm_multiplexer){ 239 free(rfcomm_multiplexer); 240 } 241 #endif 242 243 244 // MARK: rfcomm_service_t 245 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_SERVICES) 246 #if defined(MAX_NO_RFCOMM_SERVICES) 247 #error "Deprecated MAX_NO_RFCOMM_SERVICES defined instead of MAX_NR_RFCOMM_SERVICES. Please update your btstack_config.h to use MAX_NR_RFCOMM_SERVICES." 248 #else 249 #define MAX_NR_RFCOMM_SERVICES 0 250 #endif 251 #endif 252 253 #ifdef MAX_NR_RFCOMM_SERVICES 254 #if MAX_NR_RFCOMM_SERVICES > 0 255 static rfcomm_service_t rfcomm_service_storage[MAX_NR_RFCOMM_SERVICES]; 256 static btstack_memory_pool_t rfcomm_service_pool; 257 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){ 258 void * buffer = btstack_memory_pool_get(&rfcomm_service_pool); 259 if (buffer){ 260 memset(buffer, 0, sizeof(rfcomm_service_t)); 261 } 262 return (rfcomm_service_t *) buffer; 263 } 264 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){ 265 btstack_memory_pool_free(&rfcomm_service_pool, rfcomm_service); 266 } 267 #else 268 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){ 269 return NULL; 270 } 271 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){ 272 // silence compiler warning about unused parameter in a portable way 273 (void) rfcomm_service; 274 }; 275 #endif 276 #elif defined(HAVE_MALLOC) 277 rfcomm_service_t * btstack_memory_rfcomm_service_get(void){ 278 void * buffer = malloc(sizeof(rfcomm_service_t)); 279 if (buffer){ 280 memset(buffer, 0, sizeof(rfcomm_service_t)); 281 } 282 return (rfcomm_service_t *) buffer; 283 } 284 void btstack_memory_rfcomm_service_free(rfcomm_service_t *rfcomm_service){ 285 free(rfcomm_service); 286 } 287 #endif 288 289 290 // MARK: rfcomm_channel_t 291 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_RFCOMM_CHANNELS) 292 #if defined(MAX_NO_RFCOMM_CHANNELS) 293 #error "Deprecated MAX_NO_RFCOMM_CHANNELS defined instead of MAX_NR_RFCOMM_CHANNELS. Please update your btstack_config.h to use MAX_NR_RFCOMM_CHANNELS." 294 #else 295 #define MAX_NR_RFCOMM_CHANNELS 0 296 #endif 297 #endif 298 299 #ifdef MAX_NR_RFCOMM_CHANNELS 300 #if MAX_NR_RFCOMM_CHANNELS > 0 301 static rfcomm_channel_t rfcomm_channel_storage[MAX_NR_RFCOMM_CHANNELS]; 302 static btstack_memory_pool_t rfcomm_channel_pool; 303 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){ 304 void * buffer = btstack_memory_pool_get(&rfcomm_channel_pool); 305 if (buffer){ 306 memset(buffer, 0, sizeof(rfcomm_channel_t)); 307 } 308 return (rfcomm_channel_t *) buffer; 309 } 310 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){ 311 btstack_memory_pool_free(&rfcomm_channel_pool, rfcomm_channel); 312 } 313 #else 314 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){ 315 return NULL; 316 } 317 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){ 318 // silence compiler warning about unused parameter in a portable way 319 (void) rfcomm_channel; 320 }; 321 #endif 322 #elif defined(HAVE_MALLOC) 323 rfcomm_channel_t * btstack_memory_rfcomm_channel_get(void){ 324 void * buffer = malloc(sizeof(rfcomm_channel_t)); 325 if (buffer){ 326 memset(buffer, 0, sizeof(rfcomm_channel_t)); 327 } 328 return (rfcomm_channel_t *) buffer; 329 } 330 void btstack_memory_rfcomm_channel_free(rfcomm_channel_t *rfcomm_channel){ 331 free(rfcomm_channel); 332 } 333 #endif 334 335 336 337 // MARK: btstack_link_key_db_memory_entry_t 338 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES) 339 #if defined(MAX_NO_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES) 340 #error "Deprecated MAX_NO_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES defined instead of MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES. Please update your btstack_config.h to use MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES." 341 #else 342 #define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 0 343 #endif 344 #endif 345 346 #ifdef MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 347 #if MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES > 0 348 static btstack_link_key_db_memory_entry_t btstack_link_key_db_memory_entry_storage[MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES]; 349 static btstack_memory_pool_t btstack_link_key_db_memory_entry_pool; 350 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){ 351 void * buffer = btstack_memory_pool_get(&btstack_link_key_db_memory_entry_pool); 352 if (buffer){ 353 memset(buffer, 0, sizeof(btstack_link_key_db_memory_entry_t)); 354 } 355 return (btstack_link_key_db_memory_entry_t *) buffer; 356 } 357 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){ 358 btstack_memory_pool_free(&btstack_link_key_db_memory_entry_pool, btstack_link_key_db_memory_entry); 359 } 360 #else 361 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){ 362 return NULL; 363 } 364 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){ 365 // silence compiler warning about unused parameter in a portable way 366 (void) btstack_link_key_db_memory_entry; 367 }; 368 #endif 369 #elif defined(HAVE_MALLOC) 370 btstack_link_key_db_memory_entry_t * btstack_memory_btstack_link_key_db_memory_entry_get(void){ 371 void * buffer = malloc(sizeof(btstack_link_key_db_memory_entry_t)); 372 if (buffer){ 373 memset(buffer, 0, sizeof(btstack_link_key_db_memory_entry_t)); 374 } 375 return (btstack_link_key_db_memory_entry_t *) buffer; 376 } 377 void btstack_memory_btstack_link_key_db_memory_entry_free(btstack_link_key_db_memory_entry_t *btstack_link_key_db_memory_entry){ 378 free(btstack_link_key_db_memory_entry); 379 } 380 #endif 381 382 383 384 // MARK: bnep_service_t 385 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BNEP_SERVICES) 386 #if defined(MAX_NO_BNEP_SERVICES) 387 #error "Deprecated MAX_NO_BNEP_SERVICES defined instead of MAX_NR_BNEP_SERVICES. Please update your btstack_config.h to use MAX_NR_BNEP_SERVICES." 388 #else 389 #define MAX_NR_BNEP_SERVICES 0 390 #endif 391 #endif 392 393 #ifdef MAX_NR_BNEP_SERVICES 394 #if MAX_NR_BNEP_SERVICES > 0 395 static bnep_service_t bnep_service_storage[MAX_NR_BNEP_SERVICES]; 396 static btstack_memory_pool_t bnep_service_pool; 397 bnep_service_t * btstack_memory_bnep_service_get(void){ 398 void * buffer = btstack_memory_pool_get(&bnep_service_pool); 399 if (buffer){ 400 memset(buffer, 0, sizeof(bnep_service_t)); 401 } 402 return (bnep_service_t *) buffer; 403 } 404 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){ 405 btstack_memory_pool_free(&bnep_service_pool, bnep_service); 406 } 407 #else 408 bnep_service_t * btstack_memory_bnep_service_get(void){ 409 return NULL; 410 } 411 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){ 412 // silence compiler warning about unused parameter in a portable way 413 (void) bnep_service; 414 }; 415 #endif 416 #elif defined(HAVE_MALLOC) 417 bnep_service_t * btstack_memory_bnep_service_get(void){ 418 void * buffer = malloc(sizeof(bnep_service_t)); 419 if (buffer){ 420 memset(buffer, 0, sizeof(bnep_service_t)); 421 } 422 return (bnep_service_t *) buffer; 423 } 424 void btstack_memory_bnep_service_free(bnep_service_t *bnep_service){ 425 free(bnep_service); 426 } 427 #endif 428 429 430 // MARK: bnep_channel_t 431 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_BNEP_CHANNELS) 432 #if defined(MAX_NO_BNEP_CHANNELS) 433 #error "Deprecated MAX_NO_BNEP_CHANNELS defined instead of MAX_NR_BNEP_CHANNELS. Please update your btstack_config.h to use MAX_NR_BNEP_CHANNELS." 434 #else 435 #define MAX_NR_BNEP_CHANNELS 0 436 #endif 437 #endif 438 439 #ifdef MAX_NR_BNEP_CHANNELS 440 #if MAX_NR_BNEP_CHANNELS > 0 441 static bnep_channel_t bnep_channel_storage[MAX_NR_BNEP_CHANNELS]; 442 static btstack_memory_pool_t bnep_channel_pool; 443 bnep_channel_t * btstack_memory_bnep_channel_get(void){ 444 void * buffer = btstack_memory_pool_get(&bnep_channel_pool); 445 if (buffer){ 446 memset(buffer, 0, sizeof(bnep_channel_t)); 447 } 448 return (bnep_channel_t *) buffer; 449 } 450 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){ 451 btstack_memory_pool_free(&bnep_channel_pool, bnep_channel); 452 } 453 #else 454 bnep_channel_t * btstack_memory_bnep_channel_get(void){ 455 return NULL; 456 } 457 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){ 458 // silence compiler warning about unused parameter in a portable way 459 (void) bnep_channel; 460 }; 461 #endif 462 #elif defined(HAVE_MALLOC) 463 bnep_channel_t * btstack_memory_bnep_channel_get(void){ 464 void * buffer = malloc(sizeof(bnep_channel_t)); 465 if (buffer){ 466 memset(buffer, 0, sizeof(bnep_channel_t)); 467 } 468 return (bnep_channel_t *) buffer; 469 } 470 void btstack_memory_bnep_channel_free(bnep_channel_t *bnep_channel){ 471 free(bnep_channel); 472 } 473 #endif 474 475 476 477 // MARK: hfp_connection_t 478 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_HFP_CONNECTIONS) 479 #if defined(MAX_NO_HFP_CONNECTIONS) 480 #error "Deprecated MAX_NO_HFP_CONNECTIONS defined instead of MAX_NR_HFP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_HFP_CONNECTIONS." 481 #else 482 #define MAX_NR_HFP_CONNECTIONS 0 483 #endif 484 #endif 485 486 #ifdef MAX_NR_HFP_CONNECTIONS 487 #if MAX_NR_HFP_CONNECTIONS > 0 488 static hfp_connection_t hfp_connection_storage[MAX_NR_HFP_CONNECTIONS]; 489 static btstack_memory_pool_t hfp_connection_pool; 490 hfp_connection_t * btstack_memory_hfp_connection_get(void){ 491 void * buffer = btstack_memory_pool_get(&hfp_connection_pool); 492 if (buffer){ 493 memset(buffer, 0, sizeof(hfp_connection_t)); 494 } 495 return (hfp_connection_t *) buffer; 496 } 497 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){ 498 btstack_memory_pool_free(&hfp_connection_pool, hfp_connection); 499 } 500 #else 501 hfp_connection_t * btstack_memory_hfp_connection_get(void){ 502 return NULL; 503 } 504 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){ 505 // silence compiler warning about unused parameter in a portable way 506 (void) hfp_connection; 507 }; 508 #endif 509 #elif defined(HAVE_MALLOC) 510 hfp_connection_t * btstack_memory_hfp_connection_get(void){ 511 void * buffer = malloc(sizeof(hfp_connection_t)); 512 if (buffer){ 513 memset(buffer, 0, sizeof(hfp_connection_t)); 514 } 515 return (hfp_connection_t *) buffer; 516 } 517 void btstack_memory_hfp_connection_free(hfp_connection_t *hfp_connection){ 518 free(hfp_connection); 519 } 520 #endif 521 522 523 524 // MARK: service_record_item_t 525 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_SERVICE_RECORD_ITEMS) 526 #if defined(MAX_NO_SERVICE_RECORD_ITEMS) 527 #error "Deprecated MAX_NO_SERVICE_RECORD_ITEMS defined instead of MAX_NR_SERVICE_RECORD_ITEMS. Please update your btstack_config.h to use MAX_NR_SERVICE_RECORD_ITEMS." 528 #else 529 #define MAX_NR_SERVICE_RECORD_ITEMS 0 530 #endif 531 #endif 532 533 #ifdef MAX_NR_SERVICE_RECORD_ITEMS 534 #if MAX_NR_SERVICE_RECORD_ITEMS > 0 535 static service_record_item_t service_record_item_storage[MAX_NR_SERVICE_RECORD_ITEMS]; 536 static btstack_memory_pool_t service_record_item_pool; 537 service_record_item_t * btstack_memory_service_record_item_get(void){ 538 void * buffer = btstack_memory_pool_get(&service_record_item_pool); 539 if (buffer){ 540 memset(buffer, 0, sizeof(service_record_item_t)); 541 } 542 return (service_record_item_t *) buffer; 543 } 544 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){ 545 btstack_memory_pool_free(&service_record_item_pool, service_record_item); 546 } 547 #else 548 service_record_item_t * btstack_memory_service_record_item_get(void){ 549 return NULL; 550 } 551 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){ 552 // silence compiler warning about unused parameter in a portable way 553 (void) service_record_item; 554 }; 555 #endif 556 #elif defined(HAVE_MALLOC) 557 service_record_item_t * btstack_memory_service_record_item_get(void){ 558 void * buffer = malloc(sizeof(service_record_item_t)); 559 if (buffer){ 560 memset(buffer, 0, sizeof(service_record_item_t)); 561 } 562 return (service_record_item_t *) buffer; 563 } 564 void btstack_memory_service_record_item_free(service_record_item_t *service_record_item){ 565 free(service_record_item); 566 } 567 #endif 568 569 570 571 // MARK: avdtp_stream_endpoint_t 572 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVDTP_STREAM_ENDPOINTS) 573 #if defined(MAX_NO_AVDTP_STREAM_ENDPOINTS) 574 #error "Deprecated MAX_NO_AVDTP_STREAM_ENDPOINTS defined instead of MAX_NR_AVDTP_STREAM_ENDPOINTS. Please update your btstack_config.h to use MAX_NR_AVDTP_STREAM_ENDPOINTS." 575 #else 576 #define MAX_NR_AVDTP_STREAM_ENDPOINTS 0 577 #endif 578 #endif 579 580 #ifdef MAX_NR_AVDTP_STREAM_ENDPOINTS 581 #if MAX_NR_AVDTP_STREAM_ENDPOINTS > 0 582 static avdtp_stream_endpoint_t avdtp_stream_endpoint_storage[MAX_NR_AVDTP_STREAM_ENDPOINTS]; 583 static btstack_memory_pool_t avdtp_stream_endpoint_pool; 584 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){ 585 void * buffer = btstack_memory_pool_get(&avdtp_stream_endpoint_pool); 586 if (buffer){ 587 memset(buffer, 0, sizeof(avdtp_stream_endpoint_t)); 588 } 589 return (avdtp_stream_endpoint_t *) buffer; 590 } 591 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){ 592 btstack_memory_pool_free(&avdtp_stream_endpoint_pool, avdtp_stream_endpoint); 593 } 594 #else 595 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){ 596 return NULL; 597 } 598 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){ 599 // silence compiler warning about unused parameter in a portable way 600 (void) avdtp_stream_endpoint; 601 }; 602 #endif 603 #elif defined(HAVE_MALLOC) 604 avdtp_stream_endpoint_t * btstack_memory_avdtp_stream_endpoint_get(void){ 605 void * buffer = malloc(sizeof(avdtp_stream_endpoint_t)); 606 if (buffer){ 607 memset(buffer, 0, sizeof(avdtp_stream_endpoint_t)); 608 } 609 return (avdtp_stream_endpoint_t *) buffer; 610 } 611 void btstack_memory_avdtp_stream_endpoint_free(avdtp_stream_endpoint_t *avdtp_stream_endpoint){ 612 free(avdtp_stream_endpoint); 613 } 614 #endif 615 616 617 618 // MARK: avdtp_connection_t 619 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVDTP_CONNECTIONS) 620 #if defined(MAX_NO_AVDTP_CONNECTIONS) 621 #error "Deprecated MAX_NO_AVDTP_CONNECTIONS defined instead of MAX_NR_AVDTP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVDTP_CONNECTIONS." 622 #else 623 #define MAX_NR_AVDTP_CONNECTIONS 0 624 #endif 625 #endif 626 627 #ifdef MAX_NR_AVDTP_CONNECTIONS 628 #if MAX_NR_AVDTP_CONNECTIONS > 0 629 static avdtp_connection_t avdtp_connection_storage[MAX_NR_AVDTP_CONNECTIONS]; 630 static btstack_memory_pool_t avdtp_connection_pool; 631 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){ 632 void * buffer = btstack_memory_pool_get(&avdtp_connection_pool); 633 if (buffer){ 634 memset(buffer, 0, sizeof(avdtp_connection_t)); 635 } 636 return (avdtp_connection_t *) buffer; 637 } 638 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){ 639 btstack_memory_pool_free(&avdtp_connection_pool, avdtp_connection); 640 } 641 #else 642 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){ 643 return NULL; 644 } 645 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){ 646 // silence compiler warning about unused parameter in a portable way 647 (void) avdtp_connection; 648 }; 649 #endif 650 #elif defined(HAVE_MALLOC) 651 avdtp_connection_t * btstack_memory_avdtp_connection_get(void){ 652 void * buffer = malloc(sizeof(avdtp_connection_t)); 653 if (buffer){ 654 memset(buffer, 0, sizeof(avdtp_connection_t)); 655 } 656 return (avdtp_connection_t *) buffer; 657 } 658 void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection){ 659 free(avdtp_connection); 660 } 661 #endif 662 663 664 665 // MARK: avrcp_connection_t 666 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVRCP_CONNECTIONS) 667 #if defined(MAX_NO_AVRCP_CONNECTIONS) 668 #error "Deprecated MAX_NO_AVRCP_CONNECTIONS defined instead of MAX_NR_AVRCP_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVRCP_CONNECTIONS." 669 #else 670 #define MAX_NR_AVRCP_CONNECTIONS 0 671 #endif 672 #endif 673 674 #ifdef MAX_NR_AVRCP_CONNECTIONS 675 #if MAX_NR_AVRCP_CONNECTIONS > 0 676 static avrcp_connection_t avrcp_connection_storage[MAX_NR_AVRCP_CONNECTIONS]; 677 static btstack_memory_pool_t avrcp_connection_pool; 678 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){ 679 void * buffer = btstack_memory_pool_get(&avrcp_connection_pool); 680 if (buffer){ 681 memset(buffer, 0, sizeof(avrcp_connection_t)); 682 } 683 return (avrcp_connection_t *) buffer; 684 } 685 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){ 686 btstack_memory_pool_free(&avrcp_connection_pool, avrcp_connection); 687 } 688 #else 689 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){ 690 return NULL; 691 } 692 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){ 693 // silence compiler warning about unused parameter in a portable way 694 (void) avrcp_connection; 695 }; 696 #endif 697 #elif defined(HAVE_MALLOC) 698 avrcp_connection_t * btstack_memory_avrcp_connection_get(void){ 699 void * buffer = malloc(sizeof(avrcp_connection_t)); 700 if (buffer){ 701 memset(buffer, 0, sizeof(avrcp_connection_t)); 702 } 703 return (avrcp_connection_t *) buffer; 704 } 705 void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){ 706 free(avrcp_connection); 707 } 708 #endif 709 710 711 712 // MARK: avrcp_browsing_connection_t 713 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVRCP_BROWSING_CONNECTIONS) 714 #if defined(MAX_NO_AVRCP_BROWSING_CONNECTIONS) 715 #error "Deprecated MAX_NO_AVRCP_BROWSING_CONNECTIONS defined instead of MAX_NR_AVRCP_BROWSING_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVRCP_BROWSING_CONNECTIONS." 716 #else 717 #define MAX_NR_AVRCP_BROWSING_CONNECTIONS 0 718 #endif 719 #endif 720 721 #ifdef MAX_NR_AVRCP_BROWSING_CONNECTIONS 722 #if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0 723 static avrcp_browsing_connection_t avrcp_browsing_connection_storage[MAX_NR_AVRCP_BROWSING_CONNECTIONS]; 724 static btstack_memory_pool_t avrcp_browsing_connection_pool; 725 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ 726 void * buffer = btstack_memory_pool_get(&avrcp_browsing_connection_pool); 727 if (buffer){ 728 memset(buffer, 0, sizeof(avrcp_browsing_connection_t)); 729 } 730 return (avrcp_browsing_connection_t *) buffer; 731 } 732 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ 733 btstack_memory_pool_free(&avrcp_browsing_connection_pool, avrcp_browsing_connection); 734 } 735 #else 736 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ 737 return NULL; 738 } 739 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ 740 // silence compiler warning about unused parameter in a portable way 741 (void) avrcp_browsing_connection; 742 }; 743 #endif 744 #elif defined(HAVE_MALLOC) 745 avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ 746 void * buffer = malloc(sizeof(avrcp_browsing_connection_t)); 747 if (buffer){ 748 memset(buffer, 0, sizeof(avrcp_browsing_connection_t)); 749 } 750 return (avrcp_browsing_connection_t *) buffer; 751 } 752 void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ 753 free(avrcp_browsing_connection); 754 } 755 #endif 756 757 758 #ifdef ENABLE_BLE 759 760 // MARK: gatt_client_t 761 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_GATT_CLIENTS) 762 #if defined(MAX_NO_GATT_CLIENTS) 763 #error "Deprecated MAX_NO_GATT_CLIENTS defined instead of MAX_NR_GATT_CLIENTS. Please update your btstack_config.h to use MAX_NR_GATT_CLIENTS." 764 #else 765 #define MAX_NR_GATT_CLIENTS 0 766 #endif 767 #endif 768 769 #ifdef MAX_NR_GATT_CLIENTS 770 #if MAX_NR_GATT_CLIENTS > 0 771 static gatt_client_t gatt_client_storage[MAX_NR_GATT_CLIENTS]; 772 static btstack_memory_pool_t gatt_client_pool; 773 gatt_client_t * btstack_memory_gatt_client_get(void){ 774 void * buffer = btstack_memory_pool_get(&gatt_client_pool); 775 if (buffer){ 776 memset(buffer, 0, sizeof(gatt_client_t)); 777 } 778 return (gatt_client_t *) buffer; 779 } 780 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){ 781 btstack_memory_pool_free(&gatt_client_pool, gatt_client); 782 } 783 #else 784 gatt_client_t * btstack_memory_gatt_client_get(void){ 785 return NULL; 786 } 787 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){ 788 // silence compiler warning about unused parameter in a portable way 789 (void) gatt_client; 790 }; 791 #endif 792 #elif defined(HAVE_MALLOC) 793 gatt_client_t * btstack_memory_gatt_client_get(void){ 794 void * buffer = malloc(sizeof(gatt_client_t)); 795 if (buffer){ 796 memset(buffer, 0, sizeof(gatt_client_t)); 797 } 798 return (gatt_client_t *) buffer; 799 } 800 void btstack_memory_gatt_client_free(gatt_client_t *gatt_client){ 801 free(gatt_client); 802 } 803 #endif 804 805 806 // MARK: whitelist_entry_t 807 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_WHITELIST_ENTRIES) 808 #if defined(MAX_NO_WHITELIST_ENTRIES) 809 #error "Deprecated MAX_NO_WHITELIST_ENTRIES defined instead of MAX_NR_WHITELIST_ENTRIES. Please update your btstack_config.h to use MAX_NR_WHITELIST_ENTRIES." 810 #else 811 #define MAX_NR_WHITELIST_ENTRIES 0 812 #endif 813 #endif 814 815 #ifdef MAX_NR_WHITELIST_ENTRIES 816 #if MAX_NR_WHITELIST_ENTRIES > 0 817 static whitelist_entry_t whitelist_entry_storage[MAX_NR_WHITELIST_ENTRIES]; 818 static btstack_memory_pool_t whitelist_entry_pool; 819 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){ 820 void * buffer = btstack_memory_pool_get(&whitelist_entry_pool); 821 if (buffer){ 822 memset(buffer, 0, sizeof(whitelist_entry_t)); 823 } 824 return (whitelist_entry_t *) buffer; 825 } 826 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){ 827 btstack_memory_pool_free(&whitelist_entry_pool, whitelist_entry); 828 } 829 #else 830 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){ 831 return NULL; 832 } 833 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){ 834 // silence compiler warning about unused parameter in a portable way 835 (void) whitelist_entry; 836 }; 837 #endif 838 #elif defined(HAVE_MALLOC) 839 whitelist_entry_t * btstack_memory_whitelist_entry_get(void){ 840 void * buffer = malloc(sizeof(whitelist_entry_t)); 841 if (buffer){ 842 memset(buffer, 0, sizeof(whitelist_entry_t)); 843 } 844 return (whitelist_entry_t *) buffer; 845 } 846 void btstack_memory_whitelist_entry_free(whitelist_entry_t *whitelist_entry){ 847 free(whitelist_entry); 848 } 849 #endif 850 851 852 // MARK: sm_lookup_entry_t 853 #if !defined(HAVE_MALLOC) && !defined(MAX_NR_SM_LOOKUP_ENTRIES) 854 #if defined(MAX_NO_SM_LOOKUP_ENTRIES) 855 #error "Deprecated MAX_NO_SM_LOOKUP_ENTRIES defined instead of MAX_NR_SM_LOOKUP_ENTRIES. Please update your btstack_config.h to use MAX_NR_SM_LOOKUP_ENTRIES." 856 #else 857 #define MAX_NR_SM_LOOKUP_ENTRIES 0 858 #endif 859 #endif 860 861 #ifdef MAX_NR_SM_LOOKUP_ENTRIES 862 #if MAX_NR_SM_LOOKUP_ENTRIES > 0 863 static sm_lookup_entry_t sm_lookup_entry_storage[MAX_NR_SM_LOOKUP_ENTRIES]; 864 static btstack_memory_pool_t sm_lookup_entry_pool; 865 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){ 866 void * buffer = btstack_memory_pool_get(&sm_lookup_entry_pool); 867 if (buffer){ 868 memset(buffer, 0, sizeof(sm_lookup_entry_t)); 869 } 870 return (sm_lookup_entry_t *) buffer; 871 } 872 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){ 873 btstack_memory_pool_free(&sm_lookup_entry_pool, sm_lookup_entry); 874 } 875 #else 876 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){ 877 return NULL; 878 } 879 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){ 880 // silence compiler warning about unused parameter in a portable way 881 (void) sm_lookup_entry; 882 }; 883 #endif 884 #elif defined(HAVE_MALLOC) 885 sm_lookup_entry_t * btstack_memory_sm_lookup_entry_get(void){ 886 void * buffer = malloc(sizeof(sm_lookup_entry_t)); 887 if (buffer){ 888 memset(buffer, 0, sizeof(sm_lookup_entry_t)); 889 } 890 return (sm_lookup_entry_t *) buffer; 891 } 892 void btstack_memory_sm_lookup_entry_free(sm_lookup_entry_t *sm_lookup_entry){ 893 free(sm_lookup_entry); 894 } 895 #endif 896 897 898 #endif 899 // init 900 void btstack_memory_init(void){ 901 #if MAX_NR_HCI_CONNECTIONS > 0 902 btstack_memory_pool_create(&hci_connection_pool, hci_connection_storage, MAX_NR_HCI_CONNECTIONS, sizeof(hci_connection_t)); 903 #endif 904 #if MAX_NR_L2CAP_SERVICES > 0 905 btstack_memory_pool_create(&l2cap_service_pool, l2cap_service_storage, MAX_NR_L2CAP_SERVICES, sizeof(l2cap_service_t)); 906 #endif 907 #if MAX_NR_L2CAP_CHANNELS > 0 908 btstack_memory_pool_create(&l2cap_channel_pool, l2cap_channel_storage, MAX_NR_L2CAP_CHANNELS, sizeof(l2cap_channel_t)); 909 #endif 910 #if MAX_NR_RFCOMM_MULTIPLEXERS > 0 911 btstack_memory_pool_create(&rfcomm_multiplexer_pool, rfcomm_multiplexer_storage, MAX_NR_RFCOMM_MULTIPLEXERS, sizeof(rfcomm_multiplexer_t)); 912 #endif 913 #if MAX_NR_RFCOMM_SERVICES > 0 914 btstack_memory_pool_create(&rfcomm_service_pool, rfcomm_service_storage, MAX_NR_RFCOMM_SERVICES, sizeof(rfcomm_service_t)); 915 #endif 916 #if MAX_NR_RFCOMM_CHANNELS > 0 917 btstack_memory_pool_create(&rfcomm_channel_pool, rfcomm_channel_storage, MAX_NR_RFCOMM_CHANNELS, sizeof(rfcomm_channel_t)); 918 #endif 919 #if MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES > 0 920 btstack_memory_pool_create(&btstack_link_key_db_memory_entry_pool, btstack_link_key_db_memory_entry_storage, MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES, sizeof(btstack_link_key_db_memory_entry_t)); 921 #endif 922 #if MAX_NR_BNEP_SERVICES > 0 923 btstack_memory_pool_create(&bnep_service_pool, bnep_service_storage, MAX_NR_BNEP_SERVICES, sizeof(bnep_service_t)); 924 #endif 925 #if MAX_NR_BNEP_CHANNELS > 0 926 btstack_memory_pool_create(&bnep_channel_pool, bnep_channel_storage, MAX_NR_BNEP_CHANNELS, sizeof(bnep_channel_t)); 927 #endif 928 #if MAX_NR_HFP_CONNECTIONS > 0 929 btstack_memory_pool_create(&hfp_connection_pool, hfp_connection_storage, MAX_NR_HFP_CONNECTIONS, sizeof(hfp_connection_t)); 930 #endif 931 #if MAX_NR_SERVICE_RECORD_ITEMS > 0 932 btstack_memory_pool_create(&service_record_item_pool, service_record_item_storage, MAX_NR_SERVICE_RECORD_ITEMS, sizeof(service_record_item_t)); 933 #endif 934 #if MAX_NR_AVDTP_STREAM_ENDPOINTS > 0 935 btstack_memory_pool_create(&avdtp_stream_endpoint_pool, avdtp_stream_endpoint_storage, MAX_NR_AVDTP_STREAM_ENDPOINTS, sizeof(avdtp_stream_endpoint_t)); 936 #endif 937 #if MAX_NR_AVDTP_CONNECTIONS > 0 938 btstack_memory_pool_create(&avdtp_connection_pool, avdtp_connection_storage, MAX_NR_AVDTP_CONNECTIONS, sizeof(avdtp_connection_t)); 939 #endif 940 #if MAX_NR_AVRCP_CONNECTIONS > 0 941 btstack_memory_pool_create(&avrcp_connection_pool, avrcp_connection_storage, MAX_NR_AVRCP_CONNECTIONS, sizeof(avrcp_connection_t)); 942 #endif 943 #if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0 944 btstack_memory_pool_create(&avrcp_browsing_connection_pool, avrcp_browsing_connection_storage, MAX_NR_AVRCP_BROWSING_CONNECTIONS, sizeof(avrcp_browsing_connection_t)); 945 #endif 946 #ifdef ENABLE_BLE 947 #if MAX_NR_GATT_CLIENTS > 0 948 btstack_memory_pool_create(&gatt_client_pool, gatt_client_storage, MAX_NR_GATT_CLIENTS, sizeof(gatt_client_t)); 949 #endif 950 #if MAX_NR_WHITELIST_ENTRIES > 0 951 btstack_memory_pool_create(&whitelist_entry_pool, whitelist_entry_storage, MAX_NR_WHITELIST_ENTRIES, sizeof(whitelist_entry_t)); 952 #endif 953 #if MAX_NR_SM_LOOKUP_ENTRIES > 0 954 btstack_memory_pool_create(&sm_lookup_entry_pool, sm_lookup_entry_storage, MAX_NR_SM_LOOKUP_ENTRIES, sizeof(sm_lookup_entry_t)); 955 #endif 956 #endif 957 } 958