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
0035
0036 #include <ndrx_config.h>
0037 #include <string.h>
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <memory.h>
0041 #include <errno.h>
0042 #include <sys/sem.h>
0043
0044 #include <atmi.h>
0045 #include <multibuf.h>
0046 #include <atmi_shm.h>
0047 #include <ndrstandard.h>
0048 #include <ndebug.h>
0049 #include <ndrxdcmn.h>
0050 #include <userlog.h>
0051 #include <ubf_int.h>
0052 #include <typed_buf.h>
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 expublic ndrx_mbuf_ptrs_t* ndrx_mbuf_ptr_find(ndrx_mbuf_ptrs_t **ptrs, char *ptr)
0069 {
0070 ndrx_mbuf_ptrs_t *ret=NULL;
0071
0072 EXHASH_FIND_PTR( (*ptrs), ((void **)&ptr), ret);
0073
0074 return ret;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084 expublic ndrx_mbuf_ptrs_t * ndrx_mbuf_ptr_add(ndrx_mbuf_ptrs_t **ptrs, char *ptr, int tag)
0085 {
0086 ndrx_mbuf_ptrs_t *ret = NULL;
0087
0088
0089 if (NULL==(ret=(ndrx_mbuf_ptrs_t *)NDRX_FPMALLOC(sizeof(ndrx_mbuf_ptrs_t), 0)))
0090 {
0091 ndrx_TPset_error_fmt(TPEOS, "%s: Failed temporary hash space");
0092 goto out;
0093 }
0094
0095 ret->ptr = ptr;
0096 ret->tag = tag;
0097
0098
0099 if (EXFAIL!=tag)
0100 {
0101 NDRX_LOG(log_debug, "pointer %p mapped to tag %d", ptr, tag);
0102 }
0103
0104 EXHASH_ADD_PTR((*ptrs), ptr, ret);
0105
0106 out:
0107 return ret;
0108 }
0109
0110
0111
0112
0113
0114 expublic void ndrx_mbuf_ptr_free(ndrx_mbuf_ptrs_t **ptrs)
0115 {
0116 ndrx_mbuf_ptrs_t * el, *elt;
0117
0118 EXHASH_ITER(hh, (*ptrs), el, elt)
0119 {
0120 EXHASH_DEL((*ptrs), el);
0121 NDRX_FPFREE(el);
0122 }
0123 }
0124
0125
0126
0127
0128
0129
0130
0131 exprivate int ndrx_mbuf_ptrs_map_in(ndrx_growlist_t *list, UBFH *p_ub)
0132 {
0133 int ret = EXSUCCEED;
0134 Bnext_state_t state;
0135 BFLDID bfldid=BBADFLDOCC;
0136 BFLDOCC occ;
0137 char *d_ptr;
0138 char **lptr;
0139 ndrx_mbuf_vptrs_t *access_vptr;
0140 UBF_header_t *hdr = (UBF_header_t *)p_ub;
0141 int ftyp;
0142 unsigned int tag;
0143 BFLDID *p_bfldid_start = &hdr->bfldid;
0144
0145 state.p_cur_bfldid = (BFLDID *)(((char *)p_bfldid_start) + hdr->cache_ptr_off);
0146 state.cur_occ = 0;
0147 state.p_ub = p_ub;
0148 state.size = hdr->bytes_used;
0149
0150 while (EXTRUE==(ret=ndrx_Bnext(&state, p_ub, &bfldid, &occ, NULL, NULL, &d_ptr)))
0151 {
0152 ftyp = bfldid >> EFFECTIVE_BITS;
0153
0154
0155 if (BFLD_PTR==ftyp)
0156 {
0157
0158
0159
0160
0161
0162
0163
0164
0165 lptr=(char **)d_ptr;
0166 access_vptr = (ndrx_mbuf_vptrs_t *)(list->mem + ((long)(*lptr))*sizeof(ndrx_mbuf_vptrs_t));
0167
0168 NDRX_LOG(log_debug, "Mapping tag %ld to %p", (long)*lptr, access_vptr->data);
0169
0170 tag = (unsigned int)(ndrx_longptr_t)*lptr;
0171 *lptr = access_vptr->data;
0172
0173 }
0174 else if (BFLD_UBF==ftyp)
0175 {
0176
0177 if (EXSUCCEED!=ndrx_mbuf_ptrs_map_in(list, (UBFH *)d_ptr))
0178 {
0179 NDRX_LOG(log_error, "Failed to re-map master buffer %p "
0180 "sub-field (UBF) %d", p_ub, bfldid);
0181 EXFAIL_OUT(ret);
0182 }
0183 }
0184 else
0185 {
0186
0187 ret=EXSUCCEED;
0188 break;
0189 }
0190 }
0191
0192 if (EXFAIL==ret)
0193 {
0194 NDRX_LOG(log_error, "Failed to loop ubf: %s", Bstrerror(Berror));
0195 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to loop ubf: %s", Bstrerror(Berror));
0196 EXFAIL_OUT(ret);
0197 }
0198
0199 out:
0200
0201 return ret;
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 expublic int ndrx_mbuf_prepare_incoming (char *rcv_data, long rcv_len, char **odata,
0223 long *olen, long flags, long mflags)
0224 {
0225 int ret = EXSUCCEED;
0226 ndrx_growlist_t list;
0227 ndrx_mbuf_tlv_t *tlv_hdr;
0228 long tlv_pos;
0229 unsigned int tag_exp=0;
0230 ndrx_mbuf_vptrs_t current_vptr;
0231 ndrx_mbuf_vptrs_t *access_vptr;
0232 typed_buffer_descr_t *descr;
0233 int primary_loaded = EXFALSE;
0234 int i;
0235
0236 ndrx_growlist_init(&list, 50, sizeof(ndrx_mbuf_vptrs_t));
0237
0238
0239 NDRX_LOG(log_debug, "Parse incoming buffer TLV");
0240 for (tlv_pos=0; tlv_pos<rcv_len; tlv_pos+=(ALIGNED_GEN(tlv_hdr->len)+sizeof(ndrx_mbuf_tlv_t)), tag_exp++)
0241 {
0242 int is_callinfo;
0243 unsigned int tag;
0244 int btype;
0245
0246 tlv_hdr=(ndrx_mbuf_tlv_t *)(rcv_data + tlv_pos);
0247
0248 tag = NDRX_MBUF_TAGTAG(tlv_hdr->tag);
0249 btype = NDRX_MBUF_TYPE(tlv_hdr->tag);
0250 is_callinfo = !!(tlv_hdr->tag & NDRX_MBUF_CALLINFOBIT);
0251
0252 NDRX_LOG(log_debug, "Received buffer tag: %u type: %d callinfo: %d len: %ld",
0253 tag, btype, is_callinfo, tlv_hdr->len);
0254
0255 if (tag!=tag_exp)
0256 {
0257 NDRX_LOG(log_error, "ERROR: Expected tag %u but got %u", tag_exp, tag);
0258 userlog("ERROR: Expected tag %u but got %u", tag_exp, tag);
0259 ndrx_TPset_error_fmt(TPESYSTEM, "ERROR: Expected tag %u but got %u",
0260 tag_exp, tag);
0261 EXFAIL_OUT(ret);
0262 }
0263
0264
0265 descr = &G_buf_descr[btype];
0266
0267 current_vptr.btype = btype;
0268
0269 if (!primary_loaded && !is_callinfo)
0270 {
0271 current_vptr.data=*odata;
0272 current_vptr.len=*olen;
0273 }
0274 else
0275 {
0276 current_vptr.data=NULL;
0277 current_vptr.len=0;
0278 }
0279
0280
0281 ret=descr->pf_prepare_incoming(descr,
0282 tlv_hdr->data,
0283 tlv_hdr->len,
0284 ¤t_vptr.data,
0285 ¤t_vptr.len,
0286 flags);
0287
0288 if (EXSUCCEED!=ret)
0289 {
0290 NDRX_LOG(log_error, "Failed to prepare incoming buffer tag: %u type: %d callinfo: %d",
0291 tag, btype, is_callinfo);
0292 EXFAIL_OUT(ret);
0293 }
0294
0295
0296 if (EXSUCCEED!=ndrx_growlist_append(&list, ¤t_vptr))
0297 {
0298 NDRX_LOG(log_error, "Failed to append vptr list with tag: %u addr: %p len: %ld - OOM?",
0299 tag, current_vptr.data, current_vptr.len);
0300 ndrx_TPset_error_fmt(TPEOS, "Failed to append vptr list with tag: %u addr: %p len: %ld - OOM?",
0301 tag, current_vptr.data, current_vptr.len);
0302 EXFAIL_OUT(ret);
0303 }
0304
0305
0306 if (!primary_loaded && !is_callinfo)
0307 {
0308 *odata = current_vptr.data;
0309 *olen = current_vptr.len;
0310
0311
0312
0313 if (1==tag)
0314 {
0315 buffer_obj_t * buffer_info = ndrx_find_buffer(*odata);
0316
0317 if (NULL!=buffer_info->callinfobuf)
0318 {
0319 tpfree(buffer_info->callinfobuf);
0320 }
0321
0322 access_vptr = (ndrx_mbuf_vptrs_t *)list.mem;
0323 buffer_info->callinfobuf = access_vptr->data;
0324 buffer_info->callinfobuf_len = access_vptr->len;
0325 }
0326
0327 primary_loaded=EXTRUE;
0328 }
0329
0330 if (primary_loaded && is_callinfo)
0331 {
0332 NDRX_LOG(log_error, "Call info expected only for primary buffer, "
0333 "but at the tag %u", tag);
0334 ndrx_TPset_error_fmt(TPESYSTEM, "Call info expected only for primary buffer, "
0335 "but at the tag %u", tag);
0336 EXFAIL_OUT(ret);
0337 }
0338
0339 }
0340
0341 NDRX_LOG(log_debug, "Remap the vptrs (tags) to real pointers");
0342
0343
0344
0345 for (i=0; i<=list.maxindexused; i++)
0346 {
0347
0348 access_vptr = (ndrx_mbuf_vptrs_t *)(list.mem + (i)*sizeof(ndrx_mbuf_vptrs_t));
0349
0350 if (BUF_TYPE_UBF==access_vptr->btype)
0351 {
0352 if (EXSUCCEED!=ndrx_mbuf_ptrs_map_in(&list, (UBFH *)access_vptr->data))
0353 {
0354 NDRX_LOG(log_error, "Failed to re-map tag %i", i);
0355 EXFAIL_OUT(ret);
0356 }
0357 }
0358 }
0359
0360 out:
0361
0362 ndrx_growlist_free(&list);
0363
0364 return ret;
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 exprivate int ndrx_mbuf_tlv_do(char *idata, long ilen, char *obuf,
0380 long olen_max, long *olen_used, unsigned int tag, long flags)
0381 {
0382 int ret = EXSUCCEED;
0383 ndrx_mbuf_tlv_t *hdr;
0384 long new_used = ALIGNED_GEN(*olen_used);
0385 int pad=*olen_used-new_used;
0386 long tmp_olen;
0387 buffer_obj_t * buffer_info = ndrx_find_buffer(idata);
0388 typed_buffer_descr_t *descr;
0389
0390 if (NULL==buffer_info)
0391 {
0392 NDRX_LOG(log_error, "Input buffer %p not atmi allocated", idata);
0393 ndrx_TPset_error_fmt(TPEINVAL, "Input buffer %p not atmi allocated", idata);
0394 EXFAIL_OUT(ret);
0395 }
0396
0397 if (EXFAIL==ilen)
0398 {
0399
0400 ilen=buffer_info->size;
0401 }
0402
0403
0404 hdr = (ndrx_mbuf_tlv_t *)(obuf+new_used);
0405
0406
0407 new_used += sizeof(ndrx_mbuf_tlv_t);
0408
0409 if (new_used> olen_max)
0410 {
0411 ndrx_TPset_error_fmt(TPEINVAL, "%s: Internal buffer size %ld, new data %ld (tag)",
0412 __func__, olen_max, new_used);
0413 ret=EXFAIL;
0414 goto out;
0415 }
0416
0417 hdr->tag = tag | (buffer_info->type_id << NDRX_MBUF_OFFSET);
0418
0419
0420
0421
0422 tmp_olen = olen_max-new_used;
0423
0424 descr = &G_buf_descr[buffer_info->type_id];
0425
0426
0427 NDRX_LOG(log_debug, "Prep tag: %u (ttag %u, type %d). Src %p, "
0428 "dst %p olen_max=%ld new_used=%ld pad=%d buffer_left=%ld",
0429 tag, hdr->tag, buffer_info->type_id, idata, obuf, olen_max, new_used, pad, tmp_olen);
0430
0431 if (EXSUCCEED!=descr->pf_prepare_outgoing(descr, idata, ilen, hdr->data,
0432 &tmp_olen, flags))
0433 {
0434 NDRX_LOG(log_error, "ERROR: pf_prepare_outgoing failed: %u (ttag %u, type %d). Src %p, "
0435 "dst %p olen_max=%ld new_used=%ld pad=%d buffer_left=%ld: %s",
0436 tag, hdr->tag, buffer_info->type_id, idata, obuf, olen_max, new_used, pad, tmp_olen,
0437 tpstrerror(tperrno));
0438 EXFAIL_OUT(ret);
0439 }
0440 hdr->len = tmp_olen;
0441
0442 *olen_used=new_used+tmp_olen;
0443 NDRX_LOG(log_debug, "tag=%d loaded new_used=%ld", tag, *olen_used);
0444
0445 out:
0446 return ret;
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456 expublic void ndrx_mbuf_Bnext_ptr_first(UBFH *p_ub, Bnext_state_t *state)
0457 {
0458 UBF_header_t *hdr = (UBF_header_t *)p_ub;
0459 BFLDID *p_bfldid_start = &hdr->bfldid;
0460 state->p_cur_bfldid = (BFLDID *)(((char *)p_bfldid_start) + hdr->cache_ptr_off);
0461 state->cur_occ = 0;
0462 state->p_ub = p_ub;
0463 state->size = hdr->bytes_used;
0464 }
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 exprivate int ndrx_mbuf_ptrs_map_out(ndrx_mbuf_ptrs_t **ptrs, UBFH *p_ub,
0480 char *obuf, long olen_max, long *olen_used, unsigned int *p_tag, long flags)
0481 {
0482 int ret = EXSUCCEED;
0483 Bnext_state_t state;
0484 BFLDID bfldid=BBADFLDOCC;
0485 BFLDOCC occ;
0486 char *d_ptr;
0487 char **lptr;
0488 ndrx_longptr_t tmp_ptr;
0489 ndrx_mbuf_ptrs_t *hptr;
0490 int ftyp;
0491
0492 ndrx_mbuf_Bnext_ptr_first(p_ub, &state);
0493
0494 while (EXTRUE==(ret=ndrx_Bnext(&state, p_ub, &bfldid, &occ, NULL, NULL, &d_ptr)))
0495 {
0496 ftyp = bfldid >> EFFECTIVE_BITS;
0497
0498 if (BFLD_PTR==ftyp)
0499 {
0500 lptr=(char **)d_ptr;
0501
0502 if (NULL==(hptr = ndrx_mbuf_ptr_find(ptrs, *lptr)))
0503 {
0504
0505
0506
0507 *p_tag=*p_tag+1;
0508
0509 hptr = ndrx_mbuf_ptr_add(ptrs, *lptr, *p_tag);
0510
0511 if (NULL==hptr)
0512 {
0513 NDRX_LOG(log_error, "Failed to allocate ptr hash element");
0514 EXFAIL_OUT(ret);
0515 }
0516
0517 NDRX_LOG(log_debug, "fldid=%d occ=%d ptr to %p -> serialize to tag %u",
0518 bfldid, occ, *lptr, *p_tag);
0519
0520
0521
0522 if (EXSUCCEED!=ndrx_mbuf_tlv_do((char *)*lptr, EXFAIL, obuf,
0523 olen_max, olen_used, hptr->tag, flags))
0524 {
0525 NDRX_LOG(log_error, "Failed to add ptr %p to export data tag=%u",
0526 (char *)lptr, *p_tag);
0527 EXFAIL_OUT(ret);
0528 }
0529 }
0530
0531
0532 tmp_ptr=hptr->tag;
0533 *lptr = (char *)tmp_ptr;
0534 }
0535 else if (BFLD_UBF==ftyp)
0536 {
0537 NDRX_LOG(log_debug, "Processing sub-buffer field %d", bfldid);
0538 if (EXSUCCEED!=ndrx_mbuf_ptrs_map_out(ptrs, (UBFH *)d_ptr,
0539 obuf, olen_max, olen_used, p_tag, flags))
0540 {
0541 NDRX_LOG(log_error, "Sub-buffer (ubf) for fld %d failed to map");
0542 EXFAIL_OUT(ret);
0543 }
0544 }
0545 else
0546 {
0547
0548 ret=EXSUCCEED;
0549 break;
0550 }
0551 }
0552
0553 if (EXFAIL==ret)
0554 {
0555 NDRX_LOG(log_error, "Failed to loop ubf: %s", Bstrerror(Berror));
0556 ndrx_TPset_error_fmt(TPESYSTEM, "Failed to loop ubf: %s", Bstrerror(Berror));
0557 EXFAIL_OUT(ret);
0558 }
0559
0560 out:
0561 return ret;
0562 }
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582 expublic int ndrx_mbuf_prepare_outgoing (char *idata, long ilen, char *obuf, long *olen,
0583 long flags, long mflags)
0584 {
0585 int ret = EXSUCCEED;
0586 buffer_obj_t * ibuf = ndrx_find_buffer(idata);
0587 long used=0;
0588
0589 ndrx_mbuf_ptrs_t *ptrs=NULL;
0590 long tlv_pos;
0591 ndrx_mbuf_tlv_t *tlv_hdr;
0592 unsigned int ptr_tag=0;
0593
0594 if (NULL==ibuf)
0595 {
0596 NDRX_LOG(log_error, "Input buffer %p not atmi allocated", idata);
0597 ndrx_TPset_error_fmt(TPEINVAL, "Input buffer %p not atmi allocated", idata);
0598 EXFAIL_OUT(ret);
0599 }
0600
0601
0602 if (NULL!=ibuf->callinfobuf && !(mflags & NDRX_MBUF_FLAG_NOCALLINFO))
0603 {
0604 if (EXSUCCEED!=ndrx_mbuf_tlv_do(ibuf->callinfobuf, ibuf->callinfobuf_len, obuf,
0605 *olen, &used, ptr_tag | NDRX_MBUF_CALLINFOBIT, flags))
0606 {
0607 NDRX_LOG(log_error, "Failed to run TLV on callinfo");
0608 EXFAIL_OUT(ret);
0609 }
0610 ptr_tag++;
0611 }
0612
0613
0614 if (EXSUCCEED!=ndrx_mbuf_tlv_do(idata, ilen, obuf, *olen, &used,
0615 ptr_tag, flags))
0616 {
0617 NDRX_LOG(log_error, "Failed to run TLV on base buffer");
0618 EXFAIL_OUT(ret);
0619 }
0620
0621
0622
0623
0624 for (tlv_pos=0; tlv_pos<used; tlv_pos+=(ALIGNED_GEN(tlv_hdr->len)+sizeof(ndrx_mbuf_tlv_t)))
0625 {
0626 int is_callinfo;
0627
0628 tlv_hdr=(ndrx_mbuf_tlv_t *) (obuf + tlv_pos);
0629 is_callinfo = !!(tlv_hdr->tag & NDRX_MBUF_CALLINFOBIT);
0630
0631 NDRX_LOG(log_debug, "Post-processing (vptr mapping) tag: %u typed: %d callinfo: %d offset: %ld",
0632 NDRX_MBUF_TAGTAG(tlv_hdr->tag), NDRX_MBUF_TYPE(tlv_hdr->tag), is_callinfo, tlv_pos);
0633
0634
0635 if (BUF_TYPE_UBF == NDRX_MBUF_TYPE(tlv_hdr->tag))
0636 {
0637 if (EXSUCCEED!=ndrx_mbuf_ptrs_map_out(&ptrs, (UBFH *)tlv_hdr->data,
0638 obuf, *olen, &used, &ptr_tag, flags))
0639 {
0640 NDRX_LOG(log_debug, "Post-processing (vptr mapping) for tag: %d typed: %d failed callinfo: %d",
0641 NDRX_MBUF_TAGTAG(tlv_hdr->tag), NDRX_MBUF_TYPE(tlv_hdr->tag), is_callinfo);
0642 EXFAIL_OUT(ret);
0643 }
0644 }
0645 }
0646
0647
0648 *olen = used;
0649
0650 out:
0651
0652
0653 if (NULL!=ptrs)
0654 {
0655 ndrx_mbuf_ptr_free(&ptrs);
0656 }
0657
0658 NDRX_LOG(log_debug, "%ld data bytes ret=%d", *olen, ret);
0659
0660 return ret;
0661 }
0662
0663
0664
0665
0666
0667
0668 expublic void ndrx_mbuf_tlv_debug (char *rcv_data, long rcv_len)
0669 {
0670 ndrx_mbuf_tlv_t *tlv_hdr;
0671 long tlv_pos;
0672 unsigned int tag_exp=0;
0673
0674
0675 NDRX_LOG(log_debug, "** DUMP TLV START **");
0676 for (tlv_pos=0; tlv_pos<rcv_len; tlv_pos+=(ALIGNED_GEN(tlv_hdr->len)+sizeof(ndrx_mbuf_tlv_t)), tag_exp++)
0677 {
0678 int is_callinfo;
0679 unsigned int tag;
0680 int btype;
0681
0682 tlv_hdr=(ndrx_mbuf_tlv_t *)(rcv_data + tlv_pos);
0683
0684 tag = NDRX_MBUF_TAGTAG(tlv_hdr->tag);
0685 btype = NDRX_MBUF_TYPE(tlv_hdr->tag);
0686 is_callinfo = !!(tlv_hdr->tag & NDRX_MBUF_CALLINFOBIT);
0687
0688 NDRX_LOG(log_debug, "Buffer raw tag: %u tag: %u type: %d callinfo: %d len: %ld aligned: %d",
0689 tlv_hdr->tag, tag, btype, is_callinfo, tlv_hdr->len, ALIGNED_GEN(tlv_hdr->len));
0690
0691 if (tag!=tag_exp)
0692 {
0693 NDRX_LOG(log_error, "ERROR: Expected tag %u but got %u", tag_exp, tag);
0694 return;
0695 }
0696
0697 NDRX_DUMP(log_debug, "TAG data", tlv_hdr->data, tlv_hdr->len);
0698
0699 }
0700 NDRX_LOG(log_debug, "** DUMP TLV END **");
0701
0702 }
0703
0704
0705