/***
/* MPManager DDE Link C Demo App
***/

/* Includes */
#include <windows.h>
#include <stdio.h>

/* Local Defines */
#define CLIENT_FLAGS APPCMD_CLIENTONLY

/* DDE Handle Strings */
unsigned char idService[] = "MPManager";	// DDE Service is MPManager
unsigned char idTopic[] = "DDELink";		// DDE Topic is DDELink
unsigned char idItem[] = "DDEStatus";		// DDE Item is DDEStatus

/* DDE Execute Command Strings */
unsigned char msgCommSelect[] = "CommSelect|3";	// select COM3
unsigned char msgFindProgrammers[] = "FindProgrammers";	// scan for programmers
unsigned char msgImageInfo[] = "ImageInfo|1";	// read image 1 info
unsigned char msgSelect[] = "Select|1";		// Select programmer address = 1
unsigned char msgLoadImage[] = "LoadImage|1|My DDE Image|C:\\Temp\\AVR32_tag256k.hex|AT32UC3A0256|3.3|0|0";
unsigned char msgProgram[] = "Program|1|1234|Full";	// Program - all ports, full verify
unsigned char msgProgramCKV[] = "Program|1|1234|CHK";	// Program - all ports, Chksum verify
unsigned char msgPortStatus[] = "PortStatus";	// request port status
unsigned char *DataPointer;


/* DDE Callback function
* Receives asynchronous DDE messages from Server
*/
HDDEDATA CALLBACK DdeCallback(
  UINT uType,     // transaction type
  UINT uFmt,      // clipboard data format
  HCONV hconv,    // handle to the conversation
  HSZ hsz1,       // handle to a string (Topic)
  HSZ hsz2,       // handle to a string (Item)
  HDDEDATA hdata, // handle to a global memory object
  DWORD dwData1,  // transaction-specific data
  DWORD dwData2   // transaction-specific data
  ) {
	unsigned char *CB_DataPointer;
	DWORD dwCB_DataSize;
	
	switch (uType) {
	case XTYP_ADVDATA :	// Handle Advisory Data messages
		CB_DataPointer = DdeAccessData(hdata,&dwCB_DataSize);
		printf (CB_DataPointer);
		break;
	}

	return ((HDDEDATA)DDE_FACK);
}


/* Main */
void main() {
	DWORD idInst=0, dwResult, dwDataSize;
	UINT i;
	HSZ ServiceHandle, TopicHandle, ItemHandle;
	HCONV ConversationHandle;
	HDDEDATA RespHandle;


	i = DdeInitialize(&idInst,DdeCallback,CLIENT_FLAGS,0);
	if (i != DMLERR_NO_ERROR) {
		printf("*** DDE Initialize Failed ***\r\n");
		exit(1);
	}

	/* create string handles for service, topic and item */
	ServiceHandle = DdeCreateStringHandle(idInst,idService,CP_WINANSI);
	if (ServiceHandle == 0) {
		printf("*** Failed to create Service String Handle ***\r\n");
		exit(1);
	}

	TopicHandle = DdeCreateStringHandle(idInst,idTopic,CP_WINANSI);
	if (TopicHandle == 0) {
		printf("*** Failed to create Topic String Handle ***\r\n");
		exit(1);
	}

	ItemHandle = DdeCreateStringHandle(idInst,idItem,CP_WINANSI);
	if (ItemHandle == 0) {
		printf("*** Failed to create Item String Handle ***\r\n");
		exit(1);
	}

	/* Initiate conversation */
	ConversationHandle = DdeConnect(idInst, ServiceHandle, TopicHandle,NULL);
	if (ConversationHandle == 0) {
		printf("*** DDE Connect Failed ***\r\n");
		exit(1);
	}


	/* Start advisory loop */
	RespHandle = DdeClientTransaction(0,0, ConversationHandle,
						ItemHandle,1,XTYP_ADVSTART,5000,&dwResult);

	/* Request current contents of MPManager DDE Status */
	RespHandle = DdeClientTransaction(0,0, ConversationHandle,ItemHandle,1,XTYP_REQUEST,5000,&dwResult);
	if (RespHandle > 0) {
		DataPointer = DdeAccessData(RespHandle,&dwDataSize);
		printf (DataPointer);
	}

	/* Select COM */
	RespHandle = DdeClientTransaction(msgCommSelect,
						sizeof(msgCommSelect),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,1000,&dwResult);

	/* Scan for programmers */
	RespHandle = DdeClientTransaction(msgFindProgrammers,
						sizeof(msgFindProgrammers),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,30000,&dwResult);		// 30s timeout on scan

	/* Select programmer */
	RespHandle = DdeClientTransaction(msgSelect,
						sizeof(msgSelect),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,1000,&dwResult);

	Sleep(1000);	// allow MPManager time to update image info

	/* Read Image info */
	RespHandle = DdeClientTransaction(msgImageInfo,
						sizeof(msgImageInfo),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,1000,&dwResult);


	/* Load image */
	RespHandle = DdeClientTransaction(msgLoadImage,
						sizeof(msgLoadImage),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,120000,&dwResult);	// max 120s timeout on image load

	/* Program Image */
	RespHandle = DdeClientTransaction(msgProgram,
						sizeof(msgProgram),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,1000,&dwResult);

	/* Monitor Port status - Note that DDE Server will return Advisory Data only when the
		DDESTatus data value has actually changed. Use XTYP_REQUEST to access the static
		value of DDESTatus at any given time */
	for (i = 0;i<50;i++) {
		Sleep(250);
		RespHandle = DdeClientTransaction(msgPortStatus,
						sizeof(msgPortStatus),
						ConversationHandle,
						ItemHandle,0,XTYP_EXECUTE,1000,&dwResult);
	}


	Sleep(1000);

	exit(0);
}
