Post new topic Reply to topic  [ 28 posts ] 

Board index : TeleFlow Forums : General

Go to page 1, 2  Next
Author Message
 Post subject: Best Practices
PostPosted: Fri Mar 28, 2008 4:25 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
I have some general questions about best practices for writing a Teleflow program. Right now I am working on Semi-simple project that answers a call, asks for account and pin and gives the caller their info.

My First question is, is it better that, after each caller, the entire TAM reloads or should I have a GOTO tag at the end of the program that point to beginning of the Main TAM that waits for a call.

Right now I reload each time the caller hang up (assuming this flushes all the global variables as there's ALOT) but I'm not sure if that constant reloading can cause issues.

I do get an error (EXPECTION_ACCESS_VIOLATION unable to read from...) from time to time but I’m not sure it's related.


If it helps I have updated my 2007 teleflow with the 2008-0220 update pack.


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Mon Mar 31, 2008 9:21 am 
Offline

Joined: Wed Mar 19, 2003 4:28 pm
Posts: 510
Location: Canada
While reloading the application after each call is technically not incorrect, you will get your best results with TeleFlow if your application(s) only exit for an application (FATAL) error.

For a good idea of how we would suggest setting up for each call, I would recommend reviewing the Inbound New Application Template(In TeleFlow Designer, click File, New Application, New Application Template, Inbound, click OK to create the new application). Specifically, look at how the Main flowchart sets everything up, note the following, in particular:
- The first two steps set up the labels to go to in the event of a Fatal error (When your application encounters an error, the application will jump to that label), and where to go in the case of a Hang up(when your caller hangs up).
- The label for hang up runs back through the Defaults flowchart (which reinitializes all global variables, assuming you add all your globals to Defaults), and then returns to Wait for Call to await the next call.
- The fatal error label plays a polite disconnect message to the caller - if the caller is still on the line - and then exits the application. This will result in an application error log you can review to determine what went wrong.
- The DB Connect is run once, at the beginning of the application, and then not again. This may not be necessary, but illustrates something you lose by having the application exit between calls: You can have a series of steps that run whenever your application starts that don't run again. This is a good place to put any steps that are slower, that might keep TeleFlow from getting back to Wait for Call quickly. (Exits for errors are necessary, and assuming a debugged application, shouldn't be happening very often once your system is in production anyway.)


You mention "EXPECTION_ACCESS_VIOLATION"... where/when does this happen? If you have a TeleFlow line log of this error, please post it here so I can see what is happening.


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Mon Mar 31, 2008 1:07 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Seems like once it gets the error the system will keep rebooting until I restart the service. (I'm looking back further in the error log to see if maybe it could be a .dll that I have created, that is used later in the program, could be the start of the issue

2008/03/31 13:21:56.906: Setting system variable '@FATAL' to ''
2008/03/31 13:21:56.906: Setting system variable '@CALL_SEIZED' to ''
2008/03/31 13:21:56.906: Setting system variable '@CALL_START' to ''
2008/03/31 13:21:56.906: Setting system variable '@CALL_END' to ''
2008/03/31 13:21:56.906: Setting system variable '@CALL_ELAPSE' to ''
2008/03/31 13:21:56.906: Setting system variable '@WEEKDAY' to ''
2008/03/31 13:21:56.906: Setting system variable '@DATE' to ''
2008/03/31 13:21:56.906: Setting system variable '@TIME' to ''
2008/03/31 13:21:56.906: Setting system variable '@UNIX_TIME' to ''
2008/03/31 13:21:56.906: Setting system variable '@HOOK_STATUS' to ''
2008/03/31 13:21:56.906: Setting system variable '@APPID' to '1001'
2008/03/31 13:21:56.906: Setting system variable '@CALLOUT_RESULT' to ''
2008/03/31 13:21:56.906: Setting system variable '@CALLOUT_REASON' to ''
2008/03/31 13:21:56.906: Setting system variable '@TRUNK_TYPE' to ''
2008/03/31 13:21:56.906: Setting system variable '@SYS_CALLREF' to ''
2008/03/31 13:21:56.906: Initializing...

2008/03/31 13:21:56.906: 16F417C: EXCEPTION_ACCESS_VIOLATION attempting to write at location 300365B.
2008/03/31 13:21:56.906: Exception occurred! Thread exiting.
2008/03/31 13:21:59.906:


2008/03/31 13:21:59.906: Application restart 5359


2008/03/31 13:21:59.906: Setting system variable '@SYSDRIVE' to 'C:'
2008/03/31 13:21:59.906: Setting system variable '@SYSDIR' to '\Program Files\TeleFlow\Applications\RCO'
2008/03/31 13:21:59.906: Setting system variable '@P1' to ''
2008/03/31 13:21:59.906: Setting system variable '@P2' to ''
2008/03/31 13:21:59.906: Setting system variable '@P3' to ''


Last edited by crazybucky on Mon Mar 31, 2008 1:14 pm, edited 1 time in total.

Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Mon Mar 31, 2008 1:13 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
It does look like it starts with my .dll then after that bombs the program can't restart.

2008/03/31 08:55:35.890: [70] DLL Function
2008/03/31 08:55:35.890: File name is 'C:\Program Files\TeleFlow\Applications\RCO\ecc.dll'
2008/03/31 08:55:35.890: Function name is 'ecc'
2008/03/31 08:55:35.890: Parameters '@CheckECC' evaluates to 'IN01000116023 DC'
2008/03/31 08:55:35.890: Calling 'ecc("IN01000116023 DC")' from 'C:\Program Files\TeleFlow\Applications\RCO\ecc.dll'
2008/03/31 08:55:35.890: Setting global variable '@RETURNECC' to '36'
2008/03/31 08:55:35.906: 16F439B: EXCEPTION_ACCESS_VIOLATION attempting to read at location 64B9E34.
2008/03/31 08:55:35.906: Exception occurred! Thread exiting.
2008/03/31 08:55:38.906:



I'm new to c++ and wrote a simple dll to check a string and xor each character and report back the hex of the result. Maybe it's not flushing the memory when it closes?


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Mon Mar 31, 2008 6:03 pm 
Offline

Joined: Wed Mar 19, 2003 4:28 pm
Posts: 510
Location: Canada
Does the DLL Function step generate an exception when running your DLL every time? Or, does it work sometimes, and other times it causes an exception?


Did you follow the instructions per the help for the DLL Function step?

Specifically:
Use of this step requires a custom DLL that exports a function with the following properties:
· accepts a constant char* null terminated string as the sole parameter
· returns type char* that points to a dynamically allocated null terminated string that can be freed by the step

Note that the step help for this step includes an example .cpp and .h file with these properties.


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 01, 2008 7:12 am 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Most times the .dll I wrote works fine. Maybe once a day does it fail (I would say it gets used 100's of times before it fails). I'll have to look at that example as I haven't seen it.

as far as my code....

Code:
// ecc.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include <stdio.h>         // for namespace
#include <valarray>         // for Xor
#include <string>

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                )
{
    return TRUE;
}
   
   char outvalue[2] = "";
   char out [2] = "";

__declspec(dllexport) LPCTSTR ecc(LPCTSTR invalue)
{
   unsigned int v=0;
   unsigned int vlen=0;

// Setup Values of Variables
   vlen = strlen(invalue);
   outvalue[0] = invalue[0];
   
// Loop
    for(v;v<vlen-1;v++)
    {               
   outvalue [0] ^=  invalue[v+1];               
    }
   sprintf(out, "%X",2, outvalue[0]);
   
   return out;
}


Last edited by crazybucky on Wed Apr 02, 2008 6:03 pm, edited 1 time in total.

Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 01, 2008 9:45 am 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
Please confirm how many ports you are running when you get the access violation.


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 01, 2008 11:36 am 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Right now just one. But I plan on possibly using 4 to 8 lines once I get everything working.


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 01, 2008 5:01 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Acually Im not sure if it is my .dll. If it was the .dll I don't think I would have gottten the 36 back. here is some more examples...


2008/04/01 06:01:08.093: [3] TCP Send
2008/04/01 06:01:08.093: Socket handle '@SOCKET' evaluates to '1260'
2008/04/01 06:01:08.093: Message '@CheckECC@ReturnECC' evaluates to 'AT010001120210 0900C'
2008/04/01 06:01:08.093: Sending message: 'AT010001120210 0900C'
2008/04/01 06:01:08.093: [9] TCP Send
2008/04/01 06:01:08.093: Socket handle '@SOCKET' evaluates to '1260'
2008/04/01 06:01:08.093: Message is '0d'
2008/04/01 06:01:08.093: 16F41C4: EXCEPTION_ACCESS_VIOLATION attempting to write at location 3004330.
2008/04/01 06:01:08.093: Exception occurred! Thread exiting.


2008/04/01 06:01:14.593: Transactions<==Main
2008/04/01 06:01:14.593: Menu<==Transactions
2008/04/01 06:01:14.593: 16F42E2: EXCEPTION_ACCESS_VIOLATION attempting to read at location 3A363431.
2008/04/01 06:01:14.593: Exception occurred! Thread exiting.


2008/04/01 19:11:45.093: Calling 'ecc("IN0100012145 DC")' from 'C:\Program Files\TeleFlow\Applications\RCO\ecc.dll'
2008/04/01 19:11:45.093: Setting global variable '@RETURNECC' to '22'
2008/04/01 19:11:45.109: 16F3BF6: EXCEPTION_ACCESS_VIOLATION attempting to write at location 4E63D29B.
2008/04/01 19:11:45.109: Exception occurred! Thread exiting


2008/04/01 19:37:59.859: Main<==Main
2008/04/01 19:37:59.859: 152B847: EXCEPTION_ACCESS_VIOLATION attempting to read at location 3A373839.
2008/04/01 19:37:59.859: Exception occurred! Thread exiting.
2008/04/01 19:38:02.859:


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 01, 2008 6:11 pm 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
Actually, your DLL is doing something that is incompatible with TeleFlow's DLL support. TeleFlow assumes the DLL will give it a pointer to a memory location that there after belongs to TeleFlow, and TeleFlow will delete that object whether it is safe to do so or not. Therefore, your DLL must allocate memory with the "new" function. Further, it is important that your DLL function not release that memory again (with the "delete" function).

Please look at the TeleFlow help file, under the topic...

1 - Develop Applications with TeleFlow Designer
Steps Toolbox
TeleFlow Steps
Programming Steps (Prog. tab)
DLL Function

... At the bottom of the page there is a link to "getenv.cpp". This is a sample DLL function written to work with TeleFlow. It provides a tidy example of how to allocate memory that TeleFlow can later use.

Rework your DLL so it more closely matches the example, stop TeleFlow Server and replace the .DLL file you are currently using, then start TeleFlow Server again. Let us know if this makes your access violations go away.


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Wed Apr 02, 2008 6:26 am 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
I see what you’re saying. Since my data might not be in the right place, teleflow clears anything in its place. Thus causing the random crashes.


I'll work on redoing the .dll but since I’m new to c++ I can't seem to figure out that all of that sample dll. What lines in it are the important parts? I did take the sample and compile it to test and it worked but I’m not sure now what part of the sample I absolutely need. Any suggestions? Sorry to be a pain.


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Wed Apr 02, 2008 5:13 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
So I edited my code...

Code:
#include <windows.h>
#include <valarray> // for Xor
#include <string>

#include "ecc.h"




int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

  return 1;

}



char* ecc(const char* variable)

{

  // String pointer to return from function

  char* returnValue;

  // Setup Values of Variables
   
   unsigned int v=0;
    unsigned int vlen=0;
    char* value;
   char test[2] = "";

  // Allocate new strings

  returnValue = new char[2];
  value = new char[strlen(variable) + 1];

      
   
   vlen = strlen(variable);

// Copy value of variable to new string
   strcpy(value, variable);
   returnValue[0]=value[0];


for(v;v<vlen-1;v++)
{
returnValue[0] ^= value[v+1];
}


sprintf(returnValue, "%X", returnValue[0]);

  // return new string

  return(returnValue);

}


but it still seems to crash, now even more (but it does work sometime). What else am I doing wrong?


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Thu Apr 03, 2008 4:28 pm 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
char* ecc2(const char* variable)
{
// String pointer to return from function
char* returnValue = new char[3];

// Setup Values of Variables
unsigned int v=0;
unsigned int vlen=0;
char myByte = 0;

vlen = strlen(variable);

for(v=0; v<vlen; v++)
{
myByte ^= variable[v];
}

sprintf(returnValue, "%X", myByte);

// return new string
return(returnValue);
}


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Thu Apr 03, 2008 4:34 pm 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
The above code should work. The problem was that you hadn't allocated enough space in returnValue for your hex characters (2 bytes) and the NULL-termination that is added by sprintf().


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Mon Apr 07, 2008 10:01 am 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Thanks guys! You both rock. I'm playing around now with your suggestions. I've also spent a good part of the week reading up c++ and I seem to understand it a lot better now with your help. I'm trying your suggestion now and I'll let you know how it goes!


Again THANK YOU!


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Fri Apr 18, 2008 8:05 am 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Well, I'm back again. I took your advice and created a dll that I thought was stable. I even created a test teleflow app that would loop and send a large amount of random data thru the dll then wait a second and do it all over again. I ran this for over 24 hours with no issues.

But when I acually have the dll onsite and running. I can get about 50-100 calls in (each call uses the dll at least 3 time and typically 15-20 per day) before I get the errors again.


Any more suggestions? :(


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Mon Apr 21, 2008 10:20 am 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
Memory handling in C/C++ is tricky. You'll have to audit your code carefully. I've had success with Borland's "Code Guard" product to track and resolve memory errors.

I think another track my serve you better. What are you trying to do with your DLL? Perhaps I could find another way to accomplish the same thing. The sample DLL you provided earlier could have been accomplished in TeleFlow itself without resorting to an external DLL. The RunBASIC Step has an XOR function. The TeleFlow BASIC Script function name is BXOR.

Perhaps we can help you achieve your goal without writing a separate DLL.


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Mon Apr 21, 2008 2:22 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
My goal with the DLL is to take a string of letters and numbers and XOR each letter one by one then returns the 2 digit Hex value of the finial result.

For example a string of AS105 would be...


ASCII A S 1 0 5
HEX 41H 53H 31H 30H 35H


41H XOR 53H=12H
12H XOR 31H=23H
23H XOR 30H=13H
13H XOR 35H=26H

The result that I would need is the hex value 26. ( 26H = & but I can't use &)


I did see the BXOR in your basic script but I couldn't think of any other way to convert a ASCII result into a hex value.


Back to top
 Profile  
 
 Post subject: Re: Best Practices
PostPosted: Fri Apr 25, 2008 2:46 pm 
Offline
Site Admin

Joined: Wed Dec 31, 1969 5:00 pm
Posts: 329
Location: Vancouver, BC
Have you considered using the TeleFlow Hash step? The functionality you are describing suggests you are making some sort of check-sum. The Hash will create an MD5 Hash (http://en.wikipedia.org/wiki/MD5) of any string. It will be larger than one character, but may achieve the goal you need. They Encrypt and Decrypt steps may also be useful to you.

Have you had any further success with your DLL?


Back to top
 Profile WWW 
 
 Post subject: Re: Best Practices
PostPosted: Tue Apr 29, 2008 6:55 pm 
Offline

Joined: Thu Jan 31, 2008 8:54 pm
Posts: 19
Your right about the check sum. In a way it is. The bad part is that after I do my DLL it takes that check sum (i.e. 26 in this example) and adds it to the string (i.e. "AS10526"). Then TCP sends the string to a custom made server/software (a server which I have no control over). That software then validates this string with check sum and if only correct sends back the info I need with its own generated 2 digit check sum. I have tried using hash and encrypt but I can't seem to figure out if I can get the 2 digits I need consistently. I know I’m a pain, I’m sorry but I did download rad studios for that code guardian. Unfortunately, with it, I haven’t been able to build a dll that will allow teleflow to use the subroutine. Even the teleflow example doesn’t appear to work. So either I’m doing something wrong or could RAD 2007 have changed?


Back to top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 28 posts ] 

Board index : TeleFlow Forums : General

Go to page 1, 2  Next

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Style by Midnight Phoenix & N.Design Studio
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.