Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- March 28, 2013 (Thursday)
- Module: DxP.c used to create DxP.dll
- Description: This module implements the DxP communications protocol.
- */
- ///// INCLUDES
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <winsock2.h>
- #include <windows.h>
- #include "DxP.h"
- #include "dxp_common.h"
- #if defined(__cplusplus)
- #define EXPORTED extern "C" __declspec( dllexport )
- #else
- #define EXPORTED __declspec( dllexport )
- #endif
- ///// GLOBALS
- ///// STATIC GLOBALS (local to file)
- ///// STATIC FUNCTION PROTOTYPES (optional)
- ///// STATIC FUNCTION DEFINITIONS (optional)
- ///// FUNCTION DEFINITIONS
- /* Error checking should be performed in following code */
- BOOL APIENTRY LibMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- switch(fdwReason) {
- case DLL_PROCESS_ATTACH:
- /* do process initialization */
- break;
- case DLL_THREAD_ATTACH:
- /* do thread initialization */
- break;
- case DLL_THREAD_DETACH:
- /* do thread cleanup */
- break;
- case DLL_PROCESS_DETACH:
- /* do process cleanup */
- break;
- } //end switch
- return(1); /* indicate success */
- /* returning 0 indicates initialization failure */
- }
- EXPORTED int DxP(char *ipAddress, int ipPort, char *username, char *password, int cmndClass, int cmndDesc, int param, void *payload, int payloadSize, void *returnData, int *returnDataSize)
- {
- // this function implements the DxP v1.4 communications protocol
- char hello[12]; // hello string is hello-000 null terminated
- char recvbuf[MAX_RECEIVE_BUF_SIZE]; // receive buffer
- char packet[MAX_PACKET_SIZE]; // final header+payload to send to DxP device
- char byte1, byte2;
- int iResult, bytesSent, bytesRecv, packetSize;
- unsigned short newseq;
- WSADATA wsaData; // for Winsock
- SOCKET m_socket;
- struct sockaddr_in clientService;
- tHeader header;
- //printf("DxP: function entered\r\n");
- // before we do anything, we need to validate some of input parameters
- // do user name
- if(strlen(username) > MAX_USERNAME_SIZE)
- return DXP_ERROR_INVALID_PARAMETER;
- if(strlen(password) > MAX_PASSWORD_SIZE)
- return DXP_ERROR_INVALID_PARAMETER;
- ///////////////////////////////////////////////////////////////////////////////
- // setup initial hello message
- strcpy(hello, "hello-000");
- // zero out the header structure
- memset((char *)&header, 0, sizeof(tHeader));
- // zero out packet
- memset(packet, 0, sizeof(packet));
- // Initialize Winsock.
- iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
- if(iResult != NO_ERROR) {
- printf("Client: Error at WSAStartup().\n");
- return DXP_ERROR_WSA_STARTUP;
- }
- //printf("DxP: WSAStartup() called\r\n");
- // Create a socket.
- m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if(m_socket == INVALID_SOCKET) {
- //printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_SOCKET;
- }
- //printf("DxP: socket created\r\n");
- // Connect to the DxP server device.
- clientService.sin_family = AF_INET;
- clientService.sin_addr.s_addr = inet_addr(ipAddress);
- clientService.sin_port = htons(ipPort);
- if(connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) {
- //printf("Failed to connect to IP address %s, port %d\n", ipAddress, ipPort);
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_CONNECT_FAIL;
- }
- else {
- // successful connection!
- //printf("Connection made to %s\n", ipAddress);
- }
- // Send and receive data.
- // Sends Hello to Server
- //printf("DxP: sending hello...\r\n");
- bytesSent = send(m_socket, hello, 10, 0);
- if(bytesSent == SOCKET_ERROR) {
- //printf("Client: send() error %ld.\n", WSAGetLastError());
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_SEND;
- }
- //printf("DxP: hello sent, waiting for sequence #\r\n");
- // Receives Sequence from Server
- bytesRecv = recv(m_socket, recvbuf, 2, 0);
- if((bytesRecv == 0) || (bytesRecv == WSAECONNRESET)) {
- //printf("Sequence not Returned - Fail \n");
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_RECEIVE;
- }
- // convert sequence # to Sequence +1
- byte1 = recvbuf[0];
- byte2 = recvbuf[1];
- newseq = (unsigned short)byte2;
- newseq <<= 8; // shift to left 8 bits
- newseq |= byte1; // added lower 8 bits of sequence #
- newseq++; // increment to get new sequence #
- //printf("DxP: sequence # received, new sequence # is %d\r\n", newseq);
- // build header
- header.command = cmndClass;
- strcpy(header.username, username);
- strcpy(header.password, password);
- header.desc = cmndDesc;
- header.param = param;
- header.seq = newseq;
- // copy header to the packet buffer
- memcpy(packet, (char *)&header, sizeof(tHeader));
- // append the payload from the user (only if there is a payload!)
- if(payload != NULL)
- memcpy(&packet[sizeof(tHeader)], (char *)payload, payloadSize);
- // calculate packet size
- packetSize = sizeof(tHeader) + payloadSize;
- // send the packet!
- bytesSent = send(m_socket, packet, packetSize, 0);
- //printf("DxP: sent DxP payload (packet)\r\n");
- // get the response
- // receive response 0x00 is OK
- bytesRecv = recv(m_socket, recvbuf, MAX_RECEIVE_BUF_SIZE, 0);
- if((bytesRecv == 0) || (bytesRecv == WSAECONNRESET)) {
- //printf("DxP::Connection Closed by %s (bytesRecv=%d)\n", ipAddress, bytesRecv);
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_RECEIVE;
- }
- if(bytesRecv < 0) {
- //printf("DxP: bytesRecv < 0\r\n");
- closesocket(m_socket);
- WSACleanup();
- return DXP_ERROR_RECEIVE;
- }
- else {
- // we received some data, so send it back to the user!
- //printf("DxP: data receive normal-bytesRecv=%d\r\n", bytesRecv);
- memcpy((void *)returnData, recvbuf, bytesRecv);
- *returnDataSize = bytesRecv;
- }
- // We are done. Close socket
- closesocket(m_socket);
- Sleep(200); // delay to allow socket to close
- WSACleanup();
- return DXP_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement