..

RECORD NON-CONF CALL

..

Developer Group

Developer Group
Connect with thousands of other developers to brainstorm ideas, share best practices and tips - or just chat about the latest emerging technologies making noise in the field. And of course, get the most up-to-date service and support news from Dialogic.
Dialogic PowerMedia HMP GlobalCall and R4 API

RECORD NON-CONF CALL

  • Record a 1 legged call. I want to record a normal call, which would only have 1 TS, however functions like mreciottdata require two timeslots since they are designed to record a two party call.  Can someone steer me to a solution to record just a normal call? I appears that I can't open the channel from another process, but I'm unsure.  Thanks a million in advance.

  • Ok, so if you want to record the conversation of an active call, you will need to use the dx_mreciottdata, since it requires the TX timeslots from both directions. For instance recording a SIP call, you would get the timeslot of the IPM channel, and then timeslot of the dxxx device doing the plays of prompts. Or maybe you have an hairpinned IP call, so you get the timeslot of the other IPM channels. This was it records the conversation from both sides.

    Otherwise, if you only perform regular record you are only getting one direction of the conversation. Not sure which you are looking for, but both can be done in the same application or, separate application using an available DXX device then will not be targeted for use by the app itself. So you need extra voice channels in order to do so depending on how many concurrent record you want to perform.

    Jeff

  • Jeff, Thanks a million for the help.  If I understand you correctly, as long as I keep the code in the main engine I run async, I won't need another dxxx resource.  Is that correct?  Here's what I'm doing, which seems straightforward, but of course doesn't work.

    int start_rec_call(int ch)

    {

       int voxdev, ipmdev, recdev;

       DX_IOTT iott = {0};

       DV_TPT tpt = {0};

       DX_XPB xpb = {0};

       SC_TSINFO voxtsinfo, ipmtsinfo;

       long recslots[1024], voxscts, ipmscts;

       iott.io_type = IO_DEV | IO_EOT;

       iott.io_offset = 0;

       iott.io_length = -1;

       if((iott.io_fhandle = open("/audio/tmp/recordcall.vox",O_RDWR|O_TRUNC|O_CREAT,0666)) < 0) {

           dlog(ch,"Error opening call recording file");

           return(-1);

       }

       dx_clrtpt(&tpt,1);

       tpt.tp_type = IO_EOT;

       tpt.tp_termno = DX_LCOFF;

       tpt.tp_length = 1;

       tpt.tp_flags = TF_LCOFF;

       dlog(ch,"RECC:TPT setup");

       xpb.wFileFormat = FILE_FORMAT_VOX;

       xpb.wDataFormat = DATA_FORMAT_MULAW;

       xpb.nSamplesPerSec = DRT_8KHZ;

       xpb.wBitsPerSample = 8;

       dlog(ch,"RECC:XPB setup");

       voxtsinfo.sc_numts = 1;

       voxtsinfo.sc_tsarrayp = &voxscts;

       if(dx_getxmitslot(port[ch].voxfd,&voxtsinfo) == -1) {

           dlog(ch,"Error on record call getsmitslot");

           return(-1);

       }

       ipmtsinfo.sc_numts = 1;

       ipmtsinfo.sc_tsarrayp = &ipmscts;

       if(dx_getxmitslot(ipmdev,&ipmtsinfo) == -1) {

           dlog(ch,"Error on record call getsmitslot");

           return(-1);

       }

       recslots[1] = voxscts;

       recslots[0] = ipmscts;

       rectsinfo.sc_numts = 2;

       rectsinfo.sc_tsarrayp = &recslots[0];

       if(dx_mreciottdata(ipmdev,&iott, &tpt, &xpb, EV_ASYNC | TM_TONE, &rectsinfo) == -1) {

           dlog(ch,"Error starting mreciottdata on vox dev");

           dlog(ch,"Lasterr %d errmsg [%s]",ATDV_LASTERR(port[ch].voxfd),ATDV_ERRMSGP(port[ch].voxfd));

           return(-1);

       }

    }

  • Ok, a couple things seems wrong in the source you provided. One thing is you don't need LCOFF as that is for analog loop current drop (boards), and suspect this is IP if you mentioned IPM channel.

    Guess to take a step back, what software?  OS?  and protocol are you using in this case?  Board (pstn based) or IP?

    If IP, then you need to use GC/IPM APIs as well xx_getxmitslot in this case to get the incoming audio from the network.

    Jeff

  • I was a bit confused about that. My main async program under HMP Linux version 3 has run flawlessly for years. It does conferencing, IVR, outdial, etc. It uses all gc_OpenEx and scroutes, etc.  So what I need to do is record both sides of a single call. The person talking and pressing keys and the vox phrases being played on the dxxx device. I did notice the LCOFF later - my mistake as I was copying some sample code to experiment.  What I'd love to do is just record from both time slots inside my async engine, but that doesn't seem possible. So last night I just did a dx_open from an external program and I could listen to the dx side of the conversation, but not to the caller, and I'm unsure how to mix the dt,dx, gc stuff.  I basically am unsure of how to open the channel and hear both sides since the gc_OpenEX in the main engine opens both sides and routes the time slots together.  Sorry for the long answer.  So can I listen to both sides of a call where a caller has only called in and is using the IVR without disrupting the IVR call and events, or do I need to use an external program. I'm fine with buying enough extra ports to use additional ports to listen if that solves the problem.  And I really appreciate the help.  Thanks.

  • Actually this should be able to be built into the existing application just as long as you have the resources for the extra dxxx devices needed for the transaction records in this case. Upon receipt of the CONNECT or ANSWER event (pending call type) you can go straight to the separate routine for transaction record (since that what its really called in this case).

    Just take the timeslot number returned from calling both gc_GetXmitSlot (for the device handling the SIP call) and then dx_getmistslot (for the device handling the media).

    Something like this:

    port[index].tsinfoN.sc_numts = 1;

    port[index].tsinfoN.sc_tsarrayp = &(sctsN[index]);

    if (gc_GetXmitSlot(port[index].ldev, &(port[index].tsinfoN)) != GC_SUCCESS) {

    //handle error

    }

    port[index].tsinfoV.sc_numts = 1;

    port[index].tsinfoV.sc_tsarrayp = &(sctsV[index]);

    if (dx_getxmitslot(port[index].vceh, &(port[index].tsinfoV)) > 0) {

    //handle error

    }

    Then store those two values retuned from above calls in a new sc_tsinfo block similar to what is done in the docs or like I had below.

    void trans_rec_file(int idx1, int idx2)

    {

    DV_TPT tpt;

       DX_IOTT iott;

       DX_XPB xpb;

       char filename[25];

    SC_TSINFO tsinfoR;

    long tslots[2];

       xpb.wFileFormat = FILE_FORMAT_VOX;

    xpb.wDataFormat = DATA_FORMAT_MULAW;

    xpb.nSamplesPerSec = DRT_8KHZ;

    xpb.wBitsPerSample = 8;

    dx_clrtpt(&tpt, 1);

       tpt.tp_type   = IO_EOT;

       tpt.tp_termno = DX_MAXTIME;

       tpt.tp_length = 400;

       tpt.tp_flags  = TF_MAXTIME;

       sprintf(filename,"trans_%d_%d.pcm",idx1,idx2);

       if ((port[idx2].trfile = open(filename,_O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,0666)) == -1) {

    printf("Error in open: %s record file.\n",filename);

    exit(1);

       }

       iott.io_type = IO_DEV|IO_UIO|IO_EOT;

       iott.io_bufp    = 0;

       iott.io_offset  = 0;

       iott.io_length  = -1;

       iott.io_fhandle = port[idx2].trfile;

    printf("file handle: %ld\n",port[idx2].trfile);

    tslots[0] = sctsV[idx2];  // from the voice device

    tslots[1] = sctsN[idx1]; // from the network device

    tsinfoR.sc_numts = 2;

    tsinfoR.sc_tsarrayp = &tslots[0];

       printf("Start Transaction Recording on: %s\n",ATDV_NAMEP(port[idx2].vceh));

    if (dx_mreciottdata(port[idx2].vceh, &iott, &tpt, &xpb, EV_ASYNC, &tsinfoR) == -1) {

    printf("Error in dx_reciottdata: %s\n",ATDV_ERRMSGP(port[idx2].vceh));

           exit(1);

    }

    }

    Jeff

  • Thanks Jeff. I see my error. I had recording working perfectly during a two-legged conference call by listening with another dxxx device, but I thought it would work differently with a normal IVR call.  Thanks a million for the code example.

  • Jeff,

       I understand the code you sent, but one question. When I purchased new port licenses, I asked for half of the licenses to do everything, and the other half to be just resources I could use to records calls with, however I can open a dxxx device on the additional ports.  I've included a copy of the license on the ports on a dev box.  Maybe the license options were purchased wrong.  What I can do is open :N_iptB1T1:P_SIP:M_ipmB1C1:V_dxxxB1C1 on the first 2 ports but I can only open :N_iptB1T3:P_SIP:M_ipmB1C3] on ports 3 and 4, and cannot do a dx_open on those ports.  

    SERVER this_host ANY

    VENDOR INTEL

    INCREMENT Voice INTEL 110.0 permanent 4 \

       VENDOR_STRING=LIC_TYPE=Purchased,APP=HMP,HOSTID=30019B9EF30AE \

       HOSTID=0019b9ef30ae vendor_info=Vendor_Info_text \

       SN=20180601133939 TS_OK SIGN=74334C60BD3C

    INCREMENT Speech_Integration INTEL 110.0 permanent 2 \

       VENDOR_STRING=LIC_TYPE=Purchased,APP=HMP,HOSTID=30019B9EF30AE \

       HOSTID=0019b9ef30ae vendor_info=Vendor_Info_text \

       SN=20180601133939 TS_OK SIGN=7BF8E75E1A2E

    INCREMENT RTP_G_711 INTEL 110.0 permanent 4 \

       VENDOR_STRING=LIC_TYPE=Purchased,APP=HMP,HOSTID=30019B9EF30AE \

       HOSTID=0019b9ef30ae vendor_info=Vendor_Info_text \

       SN=20180601133939 TS_OK SIGN=0A0878C21DB8

    INCREMENT IP_Call_Control INTEL 110.0 permanent 4 \

       VENDOR_STRING=LIC_TYPE=Purchased,APP=IPCC,HOSTID=30019B9EF30AE \

       HOSTID=0019b9ef30ae vendor_info=Vendor_Info_text \

       SN=20180601133939 TS_OK SIGN=005F70FC5234

    INCREMENT Native_RTP INTEL 110.0 permanent 4 \

       VENDOR_STRING=LIC_TYPE=Purchased,APP=HMP,HOSTID=30019B9EF30AE \

       HOSTID=0019b9ef30ae vendor_info=Vendor_Info_text \

       SN=20180601133939 TS_OK SIGN=E230DDEA1F38

  • Ok, when you have different number of speech that is not div by 4, then it requires an extra virtual board due to underlying firmware confirmation loaded for those channels. So if you run devmapdump from DOS prompt I bet it will show the following:

    dxxxB1C1 (has FEP address for CSP component)

    dxxxB1C2 (has FEP address for CSP component)

    voice only

    dxxxB2C1

    dxxxB2C2

    Regards,.

    Jeff M.