Discussion:
Problem with DATA_B3_REQ
(too old to reply)
Kinfe Tadesse
2006-04-30 10:31:09 UTC
Permalink
Hi All,

I am trying to stream data to CAPI. i am facing a problem while trying to
send DATA_B3_REQ to CAPI. Please find the detailed description of the
problem below. I will be waiting for a recommendation to a solution
anxiously!
The statement of the problem: I have a TTS system which is integrated into
my application to speak prompts to a user. Each byte of the data the TTS
speaks need to be bit-flipped before it is sent to the TTS engine. I have
ProcessReceivedData(char* Data, WORD len) to do so. This method reverses the
bytes and calls the sendData(char * Data) method below with the reversed
data to be sent to CAPI. Please read on and find the bug in the following
code segements.

In the interest of being clear, I have tried to be specific.


I have the following Structrure definitions:
/* DATA-B3-REQUEST */

typedef struct {dword Data; word Data_Length; word Number; word Handle; word
Flags;} _DAT_B3_REQP;

/* DATA-B3-CONFIRM */

typedef struct {word Number; word Handle; word Info;} _DAT_B3_CONP;

I also have the following #defines:

#define CAPIMSG_BUF_LEN 2048 // Max length of CAPI Message buffer

#define DATA_LEN 1024 // Max data length

#define CHUNKCOUNT 7 // Number of data chunks that can be sent to CAPI

#define CAPIMSG_HEADER_LEN sizeof(CAPIMsg.header)// Length of the CAPI Msg
header (12 bytes)

#define _DATA_B3_R 0x8086 //command and subcommand are merged into a
WORD

#define _DATA_B3_I 0x8286 //command and subcommand are merged into a
WORD

/* OR this to convert a REQUEST to a CONFIRM */

#define CONFIRM 0x0100

/* OR this to convert a INDICATION to a RESPONSE */

#define RESPONSE 0x0100

The following global variables are also defined:

DWORD dwApplId = 0; // Appl. Id. #

WORD wCAPICmd =0;

WORD wCtrl = 1; // Controller #

WORD wDataLen = 0; // Data Len #

WORD wDataHandle =0; //Data Handle

BYTE bPLCI = 0; // PLCI #

WORD wNCCI = 0; // NCCI #

char szDataBuf[DATA_LEN]; // Data buffer #

The following function is meant to fill a buffer with data and send
DATA_B3_REQ and get confirmation from CAPI.

void SendData(char *Data){


DWORD dwApplId=0;

static WORD wDataHandle;

int i=0;

while(i<CHUNKCOUNT && Data !=NULL){

for(int j=0;j<DATA_LEN;j++){

szDataBuf[j]= Data[j];

i++;}}

if( PutCAPIDataReq(dwApplId) != FALSE ){

GetCAPIDataConf(dwApplId) ;

wDataHandle++; //To make the data handle unique}}

*-------------------------------------------------------------------

* PutCAPIDataReq()

*-------------------------------------------------------------------*/

BOOL PutCAPIDataReq(DWORD dwApplId){

DWORD dwRetCode;

CAPI_MSG CAPIMsg;


memset(&CAPIMsg, 0, sizeof(CAPIMsg));


CAPIMsg.header.appl_id = (WORD)dwApplId;

CAPIMsg.header.controller = (BYTE)wCtrl;

CAPIMsg.header.plci = bPLCI;

CAPIMsg.header.ncci = wNCCI;

CAPIMsg.header.command = _DATA_B3_R;

CAPIMsg.header.length = CAPIMSG_HEADER_LEN + sizeof(_DAT_B3_REQP);

CAPIMsg.info.data_b3_req.Handle = wDataHandle;

CAPIMsg.info.data_b3_req.Data_Length = DATA_LEN;

CAPIMsg.info.data_b3_req.Data = (DWORD) &szDataBuf;

CAPIMsg.info.data_b3_req.Number = 0; // Always use same handle: 0

CAPIMsg.info.data_b3_req.Flags = 0; // No flags.


dwRetCode = CAPI_PUT_MESSAGE( dwApplId, &CAPIMsg);

if (dwRetCode != SUCCESS)

{

printf("\n[ERROR] CAPI_PUT_MESSAGE DATA_B3_REQ failed, error
0x%04X.",dwRetCode);

return FALSE;

}

printf("\n[OK ] CAPI_PUT_MESSAGE.DATA_B3_REQ");

return TRUE;


}

The call to PutCAPIDataReq(dwApplId) always returns FALSE and CONFIRM is
never done! But for completeness please find the Confirmation function
below.

/*-------------------------------------------------------------------

* GetCAPIDataConf()

* -------------------------------------------------------------------*/

BOOL GetCAPIDataConf(DWORD dwApplId){

CAPI_MSG *CAPIMessage=NULL;


//Wait for a DATA_B3_CONF

do{

CAPIMessage = WaitForConfirmation(dwApplId);// function waiting for
confirmation message

}while(!(CAPIMessage->header.command & _DATA_B3_R));


if(CAPIMessage->info.data_b3_con.Info!= SUCCESS)

{

printf("\n==>: DATA_B3_CONF NOT OK, Info =
0x%04X",CAPIMessage->info.data_b3_con.Info);

return FALSE;

}

printf("\n[OK ] RECEIVED DATA_B3_CONF: DATA CONFIRMATION OK.");

return TRUE;

}

This has become a stumbling block and I appreciate any help!!!

Best regards,

Kinfe T.
Werner Henze
2006-04-30 18:48:09 UTC
Permalink
Hi!
Please read on and find the bug in the following code segements.
Please do not make it too easy for us, who might want to help you.
The call to PutCAPIDataReq(dwApplId) always returns FALSE and CONFIRM is
never done!
And what error code do you get from CAPI_PUT_MESSAGE?
But for completeness please find the Confirmation function below.
Your code is very bad designed. Reading all messages until you get
a DATA_B3_CONF (and ignoring all other messages) is very bad. What
about DISCONNECT_B3_IND oder DISCONNECT_IND?
Sending one block of data, waiting for the DATA_B3_CONF and then
sending the next block of data is crap. For keeping the send queue
filled you want to send n buffers initially and upon each DATA_B3_CONF
you send the next data block. This way you always have n buffers
outstanding at CAPI.

Ciao,
Werner...
--
PGP 8 available
http://home.arcor.de/werner.henze
Kinfe Tadesse
2006-05-01 08:56:55 UTC
Permalink
Dear Werner Henz,

Thank you for the reply.
Post by Werner Henze
Please do not make it too easy for us, who might want to help you.
What do you mean?
Post by Werner Henze
Post by Kinfe Tadesse
The call to PutCAPIDataReq(dwApplId) always returns FALSE and CONFIRM is
never done!
And what error code do you get from CAPI_PUT_MESSAGE?
It generates the Error code 0x1101 which stands for WRONG APPLICATION ID. I
did something not logical to avoid this problem (I set the applId in the
SendData() funtion to 1) then it started playing but the DATA_B3_CONF
problem you pointed out started happening.
Post by Werner Henze
Your code is very bad designed. Reading all messages until you get
a DATA_B3_CONF (and ignoring all other messages) is very bad.
I know it is not a good one but it worked for other confirmation messages.
Do you mind suggesting a better approach? Thank you in advance.
Post by Werner Henze
What about DISCONNECT_B3_IND oder DISCONNECT_IND?
What do you mean?
Post by Werner Henze
Sending one block of data, waiting for the DATA_B3_CONF and then
sending the next block of data is crap. For keeping the send queue
filled you want to send n buffers initially and upon each DATA_B3_CONF
you send the next data block. This way you always have n buffers
outstanding at CAPI.
I am trying to do this!

Thanks!

Best regards,

Kinfe T
Werner Henze
2006-05-01 15:05:04 UTC
Permalink
Hi!
Post by Kinfe Tadesse
Post by Werner Henze
Please do not make it too easy for us, who might want to help you.
What do you mean?
Hiding the error message in the source code makes it as easy as
possible, doesn't it?
Post by Kinfe Tadesse
It generates the Error code 0x1101 which stands for WRONG APPLICATION ID. I
did something not logical to avoid this problem (I set the applId in the
SendData() funtion to 1) then it started playing but the DATA_B3_CONF
problem you pointed out started happening.
So give it the right ApplID - it is the one you get from CAPI_REGISTER.
Post by Kinfe Tadesse
I know it is not a good one but it worked for other confirmation messages.
Do you mind suggesting a better approach? Thank you in advance.
Implement a state machine. Have an extra thread or at least a main loop
that is sending to and receiving from CAPI. What to do upon receival of
a CAPI message would be decided based on the state.
Post by Kinfe Tadesse
Post by Werner Henze
What about DISCONNECT_B3_IND oder DISCONNECT_IND?
What do you mean?
You send a DATA_B3_REQ and receive messages until you receive a
DATA_B3_CONF. What if you receive a DISCONNECT_B3_IND? Your code simply
ignores the DISCONNECT_B3_IND and does not send the DISCONNECT_B3_RESP.

Ciao,
Werner...
--
PGP 8 available
http://home.arcor.de/werner.henze
Continue reading on narkive:
Loading...