0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <errno.h>
0038 #include <sys_primitives.h>
0039 #include <utlist.h>
0040
0041 #include <atmi.h>
0042 #include <atmi_int.h>
0043 #include <ubf.h>
0044 #include <ndrstandard.h>
0045 #include <atmi_int.h>
0046 #include <typed_buf.h>
0047 #include <ndebug.h>
0048 #include <thlock.h> /* muli thread support */
0049 #include <typed_string.h>
0050 #include <typed_json.h>
0051 #include <typed_carray.h>
0052 #include <typed_view.h>
0053 #include <tperror.h>
0054 #include <tpadm.h>
0055
0056 #include "atmi_tls.h"
0057
0058
0059
0060
0061
0062 exprivate buffer_obj_t * find_buffer_int(char *ptr);
0063
0064
0065
0066 expublic buffer_obj_t *ndrx_G_buffers=NULL;
0067
0068 exprivate MUTEX_LOCKDECL(M_lock);
0069
0070
0071
0072
0073 expublic typed_buffer_descr_t G_buf_descr[] =
0074 {
0075 {BUF_TYPE_UBF, "UBF", "FML", NULL, UBF_prepare_outgoing, UBF_prepare_incoming,
0076 UBF_tpalloc, UBF_tprealloc, UBF_tpfree, UBF_test},
0077
0078 {BUF_TYPE_UBF, "UBF32", "FML32", NULL, UBF_prepare_outgoing, UBF_prepare_incoming,
0079 UBF_tpalloc, UBF_tprealloc, UBF_tpfree, UBF_test},
0080 {BUF_TYPE_INIT, "TPINIT", NULL, NULL, NULL, NULL,
0081 TPINIT_tpalloc, NULL, TPINIT_tpfree, NULL},
0082
0083 {BUF_TYPE_NULL, "NULL", NULL, NULL, TPNULL_prepare_outgoing, TPNULL_prepare_incoming,
0084 TPNULL_tpalloc, NULL, TPNULL_tpfree, NULL},
0085
0086 {BUF_TYPE_STRING, "STRING", NULL, NULL, STRING_prepare_outgoing, STRING_prepare_incoming,
0087 STRING_tpalloc, STRING_tprealloc, STRING_tpfree, STRING_test},
0088
0089 {BUF_TYPE_CARRAY, "CARRAY", "X_OCTET", NULL, CARRAY_prepare_outgoing, CARRAY_prepare_incoming,
0090 CARRAY_tpalloc, CARRAY_tprealloc, CARRAY_tpfree, CARRAY_test},
0091 {BUF_TYPE_JSON, "JSON", NULL, NULL, JSON_prepare_outgoing, JSON_prepare_incoming,
0092 JSON_tpalloc, JSON_tprealloc, JSON_tpfree, JSON_test},
0093 {BUF_TYPE_VIEW, "VIEW", "VIEW32", NULL, VIEW_prepare_outgoing, VIEW_prepare_incoming,
0094 VIEW_tpalloc, VIEW_tprealloc, VIEW_tpfree, VIEW_test},
0095 {EXFAIL}
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 exprivate int buf_ptr_cmp_fn(buffer_obj_t *a, buffer_obj_t *b)
0109 {
0110 return (a->buf==b->buf?EXSUCCEED:EXFAIL);
0111 }
0112
0113
0114
0115
0116
0117
0118
0119 expublic int ndrx_buffer_list(ndrx_growlist_t *list)
0120 {
0121 int ret = EXSUCCEED;
0122 int i = 0;
0123 buffer_obj_t *elt, *tmp;
0124
0125 ndrx_growlist_init(list, 100, sizeof(void *));
0126
0127 MUTEX_LOCK_V(M_lock);
0128 EXHASH_ITER(hh,ndrx_G_buffers,elt,tmp)
0129 {
0130 ndrx_growlist_add(list, elt->buf, i);
0131 i++;
0132 }
0133 MUTEX_UNLOCK_V(M_lock);
0134
0135 out:
0136
0137 if (EXSUCCEED!=ret)
0138 {
0139 ndrx_growlist_free(list);
0140 }
0141
0142 return ret;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 expublic buffer_obj_t * ndrx_find_buffer(char *ptr)
0155 {
0156 buffer_obj_t *ret;
0157
0158 if (NULL==ptr)
0159 {
0160 return &G_atmi_tls->nullbuf;
0161 }
0162
0163 MUTEX_LOCK_V(M_lock);
0164 EXHASH_FIND_PTR( ndrx_G_buffers, ((void **)&ptr), ret);
0165 MUTEX_UNLOCK_V(M_lock);
0166
0167 return ret;
0168
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178 exprivate buffer_obj_t * find_buffer_int(char *ptr)
0179 {
0180 buffer_obj_t *ret=NULL;
0181
0182
0183
0184
0185
0186
0187 if (NULL==ptr)
0188 {
0189 return &G_atmi_tls->nullbuf;
0190 }
0191
0192 EXHASH_FIND_PTR( ndrx_G_buffers, ((void **)&ptr), ret);
0193
0194 return ret;
0195 }
0196
0197
0198
0199
0200
0201
0202
0203 expublic typed_buffer_descr_t * ndrx_get_buffer_descr(char *type, char *subtype)
0204 {
0205 typed_buffer_descr_t *p=G_buf_descr;
0206 typed_buffer_descr_t *ret = NULL;
0207
0208 while (EXFAIL!=p->type_id)
0209 {
0210 if ((NULL!=p->type && 0==strcmp(p->type, type)) ||
0211 (NULL!=p->alias && 0==strcmp(p->alias, type)) ||
0212 p->type == type )
0213 {
0214
0215 ret=p;
0216 break;
0217 }
0218 p++;
0219 }
0220 return ret;
0221 }
0222
0223
0224
0225
0226
0227
0228
0229
0230 expublic char * ndrx_tpalloc (typed_buffer_descr_t *known_type,
0231 char *type, char *subtype, long len)
0232 {
0233 char *ret=NULL;
0234 typed_buffer_descr_t *usr_type = NULL;
0235 buffer_obj_t *node;
0236
0237 NDRX_LOG(log_debug, "%s: type=%s, subtype=%s len=%d",
0238 __func__, (NULL==type?"NULL":type),
0239 (NULL==subtype?"NULL":subtype), len);
0240
0241 if (NULL==known_type)
0242 {
0243 if (NULL==(usr_type = ndrx_get_buffer_descr(type, subtype)))
0244 {
0245 ndrx_TPset_error_fmt(TPEOTYPE, "Unknown type (%s)/subtype(%s)",
0246 (NULL==type?"NULL":type), (NULL==subtype?"NULL":subtype));
0247 ret=NULL;
0248 goto out;
0249 }
0250 }
0251 else
0252 {
0253
0254 usr_type = known_type;
0255 }
0256
0257
0258 if (NULL==(ret=usr_type->pf_alloc(usr_type, subtype, &len)))
0259 {
0260
0261 goto out;
0262 }
0263
0264
0265 if (NULL==(node=(buffer_obj_t *)NDRX_FPMALLOC(sizeof(buffer_obj_t), 0)))
0266 {
0267 ndrx_TPset_error_fmt(TPEOS, "%s: Failed to allocate buffer list node: %s", __func__,
0268 strerror(errno));
0269 ret=NULL;
0270
0271 goto out;
0272 }
0273
0274
0275 memset(node, 0, sizeof(buffer_obj_t));
0276
0277 node->buf = ret;
0278 NDRX_LOG(log_debug, "%s: type=%s subtype=%s len=%d allocated=%p",
0279 __func__, usr_type->type,
0280 (NULL==subtype?"NULL":subtype),
0281 len, ret);
0282 node->size = len;
0283
0284 node->type_id = usr_type->type_id;
0285
0286 if (NULL==subtype)
0287 {
0288 node->subtype[0] = EXEOS;
0289 }
0290 else
0291 {
0292 NDRX_STRCPY_SAFE(node->subtype, subtype);
0293 }
0294
0295 MUTEX_LOCK_V(M_lock);
0296
0297
0298 EXHASH_ADD_PTR(ndrx_G_buffers, buf, node);
0299 MUTEX_UNLOCK_V(M_lock);
0300
0301 out:
0302
0303 return ret;
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 expublic char * ndrx_tprealloc (char *buf, long len)
0313 {
0314 char *ret=NULL;
0315 buffer_obj_t * node;
0316 typed_buffer_descr_t *buf_type = NULL;
0317
0318 NDRX_LOG(log_debug, "%s buf=%p, len=%ld", __func__, buf, len);
0319
0320 if (NULL==buf)
0321 {
0322
0323 goto out_nolock;
0324 }
0325
0326 if (NULL==(node=ndrx_find_buffer(buf)))
0327 {
0328 MUTEX_UNLOCK_V(M_lock);
0329 ndrx_TPset_error_fmt(TPEINVAL, "%s: Buffer %p is not know to system",
0330 __func__, buf);
0331 ret=NULL;
0332 goto out;
0333 }
0334
0335 NDRX_LOG(log_debug, "%s buf=%p autoalloc=%hd",
0336 __func__, buf, node->autoalloc);
0337
0338 buf_type = &G_buf_descr[node->type_id];
0339
0340
0341
0342
0343
0344
0345 MUTEX_LOCK_V(M_lock);
0346 EXHASH_DEL(ndrx_G_buffers, node);
0347 MUTEX_UNLOCK_V(M_lock);
0348
0349
0350
0351
0352 if (NULL==(ret=buf_type->pf_realloc(buf_type, buf, len)))
0353 {
0354 ret=NULL;
0355 goto out;
0356 }
0357
0358 node->buf = ret;
0359
0360
0361 MUTEX_LOCK_V(M_lock);
0362 EXHASH_ADD_PTR(ndrx_G_buffers, buf, node);
0363 MUTEX_UNLOCK_V(M_lock);
0364
0365 node->size = len;
0366
0367 out:
0368
0369 out_nolock:
0370 return ret;
0371
0372 }
0373
0374
0375
0376
0377
0378
0379 exprivate void scan_ptrs(UBFH *p_ub, ndrx_buf_free_lists_t *flist)
0380 {
0381 int ret = EXSUCCEED;
0382 Bnext_state_t state;
0383 BFLDID bfldid=BBADFLDOCC;
0384 BFLDOCC occ;
0385 char *d_ptr;
0386 char **lptr;
0387 int ftyp;
0388
0389 ndrx_mbuf_Bnext_ptr_first(p_ub, &state);
0390
0391 while (EXTRUE==(ret=ndrx_Bnext(&state, p_ub, &bfldid, &occ, NULL, NULL, &d_ptr)))
0392 {
0393 ftyp = bfldid >> EFFECTIVE_BITS;
0394
0395 if (BFLD_PTR==ftyp)
0396 {
0397
0398
0399 lptr=(char **)d_ptr;
0400
0401 if (NULL!=*lptr)
0402 {
0403 buffer_obj_t *buf = ndrx_find_buffer(*lptr);
0404
0405 if (NULL!=buf && BUF_TYPE_UBF==buf->type_id)
0406 {
0407
0408 scan_ptrs((UBFH *)*lptr, flist);
0409 }
0410 }
0411
0412
0413 if (NULL!=*lptr &&
0414 *lptr!=flist->mainbuf &&
0415 NULL==ndrx_mbuf_ptr_find(&flist->ptrs_hash, *lptr))
0416 {
0417
0418 ndrx_mbuf_ptr_add(&flist->ptrs_hash, *lptr, EXFAIL);
0419 }
0420 }
0421 else if (BFLD_UBF==ftyp)
0422 {
0423 scan_ptrs((UBFH *)d_ptr, flist);
0424 }
0425 }
0426 }
0427
0428
0429
0430
0431
0432
0433
0434 expublic void ndrx_tpfree_inner (char *buf, buffer_obj_t *known_buffer, ndrx_buf_free_lists_t *flist)
0435 {
0436 buffer_obj_t *elt;
0437 typed_buffer_descr_t *buf_type = NULL;
0438 tp_command_call_t * last_call;
0439
0440 NDRX_LOG(log_debug, "_tpfree buf=%p", buf);
0441
0442 if (NULL==buf)
0443 {
0444
0445 return;
0446 }
0447
0448
0449 if (NULL!=known_buffer)
0450 elt=known_buffer;
0451 else
0452 {
0453 elt=ndrx_find_buffer(buf);
0454 }
0455
0456 if (NULL!=elt)
0457 {
0458
0459 last_call = ndrx_get_G_last_call();
0460
0461 if (elt==last_call->autobuf)
0462 {
0463
0464
0465
0466 last_call->autobuf = NULL;
0467 }
0468
0469 buf_type = &G_buf_descr[elt->type_id];
0470
0471
0472 if (NULL!=elt->callinfobuf)
0473 {
0474 NDRX_LOG(log_debug, "Removing call info buffer %p", elt->callinfobuf);
0475
0476
0477
0478 if (NULL!=flist)
0479 {
0480 scan_ptrs((UBFH *)elt->callinfobuf, flist);
0481 }
0482
0483
0484
0485
0486 ndrx_tpfree(elt->callinfobuf, NULL);
0487 }
0488
0489
0490
0491 MUTEX_LOCK_V(M_lock);
0492 EXHASH_DEL(ndrx_G_buffers, elt);
0493 MUTEX_UNLOCK_V(M_lock);
0494
0495
0496 if (BUF_TYPE_UBF==buf_type->type_id && NULL!=flist)
0497 {
0498 scan_ptrs((UBFH *)buf, flist);
0499 }
0500
0501
0502 buf_type->pf_free(buf_type, elt->buf);
0503
0504
0505 NDRX_FPFREE(elt);
0506
0507 if (NULL!=flist)
0508 {
0509
0510 ndrx_mbuf_ptrs_t *el, *elt;
0511
0512 EXHASH_ITER(hh, flist->ptrs_hash, el, elt)
0513 {
0514 ndrx_tpfree_inner(el->ptr, NULL, NULL);
0515
0516 EXHASH_DEL(flist->ptrs_hash, el);
0517 NDRX_FPFREE(el);
0518 }
0519 }
0520 }
0521
0522 out:
0523 return;
0524 }
0525
0526
0527
0528
0529
0530
0531
0532
0533 expublic void ndrx_tpfree (char *buf, buffer_obj_t *known_buffer)
0534 {
0535 ndrx_buf_free_lists_t flist;
0536
0537 memset(&flist, 0, sizeof(flist));
0538
0539
0540
0541
0542
0543 ndrx_tpfree_inner (buf, known_buffer, &flist);
0544 }
0545
0546
0547
0548
0549
0550
0551 expublic int ndrx_tpisautobuf(char *buf)
0552 {
0553 int ret;
0554 buffer_obj_t *elt;
0555
0556
0557 if (NULL==buf)
0558 {
0559 return EXTRUE;
0560 }
0561
0562 elt=ndrx_find_buffer(buf);
0563
0564 if (NULL!=elt)
0565 {
0566 ret = elt->autoalloc;
0567 NDRX_LOG(log_debug, "_tpisautobuf buf=%p, autoalloc=%d", buf, ret);
0568 }
0569 else
0570 {
0571 ndrx_TPset_error_msg(TPEINVAL, "ptr points to unknown buffer, "
0572 "not allocated by tpalloc()!");
0573 ret=EXFAIL;
0574 }
0575
0576 return ret;
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586 expublic long ndrx_tptypes (char *ptr, char *type, char *subtype)
0587 {
0588 long ret=EXSUCCEED;
0589
0590 typed_buffer_descr_t *buf_type = NULL;
0591 buffer_obj_t *buf;
0592
0593 buf = ndrx_find_buffer(ptr);
0594
0595 if (NULL==buf)
0596 {
0597 ndrx_TPset_error_msg(TPEINVAL, "ptr points to unknown buffer, "
0598 "not allocated by tpalloc()!");
0599 ret=EXFAIL;
0600 goto out;
0601 }
0602 else
0603 {
0604 ret = buf->size;
0605 }
0606
0607 buf_type = &G_buf_descr[buf->type_id];
0608
0609 if (NULL!=type)
0610 {
0611
0612 strcpy(type, buf_type->type);
0613 }
0614
0615 if (NULL!=subtype && EXEOS!=buf->subtype[0])
0616 {
0617 strcpy(subtype, buf->subtype);
0618 }
0619
0620 out:
0621
0622 return ret;
0623
0624 }
0625
0626
0627
0628
0629
0630
0631
0632
0633 expublic int ndrx_tpsetcallinfo(const char *msg, UBFH *cibuf, long flags)
0634 {
0635 int ret = EXSUCCEED;
0636 buffer_obj_t * node_msg;
0637 typed_buffer_descr_t *descr = &G_buf_descr[BUF_TYPE_UBF];
0638
0639 NDRX_LOG(log_debug, "Setting call info primary buffer msg=%p, cibuf=%p, flags=%ld",
0640 msg, cibuf, flags);
0641
0642
0643 if (NULL==(node_msg=ndrx_find_buffer((char *)msg)))
0644 {
0645 ndrx_TPset_error_fmt(TPEINVAL, "msg buffer %p is not know to system", msg);
0646 EXFAIL_OUT(ret);
0647 }
0648
0649
0650 if (EXSUCCEED!=descr->pf_prepare_incoming(descr, (char *)cibuf, Bused(cibuf),
0651 &(node_msg->callinfobuf), &node_msg->callinfobuf_len, 0))
0652 {
0653 NDRX_LOG(log_error, "Failed to setup call info buffer: %s", tpstrerror(tperrno));
0654 EXFAIL_OUT(ret);
0655 }
0656
0657 out:
0658 return ret;
0659 }
0660
0661
0662
0663
0664
0665
0666
0667
0668 expublic int ndrx_tpgetcallinfo(const char *msg, UBFH **cibuf, long flags)
0669 {
0670 int ret = EXSUCCEED;
0671 buffer_obj_t * node_msg;
0672 typed_buffer_descr_t *callbuf = &G_buf_descr[BUF_TYPE_UBF];
0673 long olen=0;
0674
0675 NDRX_LOG(log_debug, "Setting call info primary buffer msg=%p, obuf=%p, flags=%ld",
0676 msg, cibuf, flags);
0677
0678
0679 if (NULL==(node_msg=ndrx_find_buffer((char *)msg)))
0680 {
0681 ndrx_TPset_error_fmt(TPEINVAL, "msg buffer %p is not know to system", msg);
0682 EXFAIL_OUT(ret);
0683 }
0684
0685 if (NULL==node_msg->callinfobuf)
0686 {
0687 if (flags & TPCI_NOEOFERR)
0688 {
0689 NDRX_LOG(log_debug, "No call infos associated with buffer %p", msg);
0690 goto out;
0691 }
0692 else
0693 {
0694 ndrx_TPset_error_fmt(TPESYSTEM, "No call info buffer is associated with message");
0695 EXFAIL_OUT(ret);
0696 }
0697 }
0698
0699
0700 if (EXSUCCEED!=callbuf->pf_prepare_incoming(callbuf, node_msg->callinfobuf,
0701 node_msg->callinfobuf_len, (char **)cibuf, &olen, 0))
0702 {
0703 NDRX_LOG(log_error, "Failed to retrieve call infos: %s", tpstrerror(tperrno));
0704 EXFAIL_OUT(ret);
0705 }
0706
0707
0708 if (flags & TPCI_NOEOFERR)
0709 {
0710 ret=EXTRUE;
0711 }
0712
0713 out:
0714 return ret;
0715 }
0716