Ejemplo n.º 1
0
UDBSocket UDBSocket_init(UDBSocketType type, uint16_t UDP_port, char* UDP_host, char* serial_port, long serial_baud)
{
	UDBSocket newSocket = (UDBSocket)malloc(sizeof(UDBSocket_t));
	if (!newSocket)
	{
		return NULL;
	}
	memset((char*)newSocket, 0, sizeof(UDBSocket_t));
	newSocket->type = type;
	newSocket->UDP_port = UDP_port;
	newSocket->UDP_host = (UDP_host) ? _strdup(UDP_host) : NULL;
	newSocket->serial_port = (serial_port) ? _strdup(serial_port) : NULL;
	newSocket->serial_baud = serial_baud;

	switch (newSocket->type)
	{
		case UDBSocketStandardInOut:
		{
			SetTermIOs();
			break;
		}
		case UDBSocketUDPClient:
		{
			u_long on = 1;
			if (!hasInitializedWSA)
			{
				if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
				{
					snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "WSAStartup Failed. Error Code : %d", WSAGetLastError());
					return NULL;
				}
				hasInitializedWSA = 1;
			}
			if ((newSocket->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "socket() failed.  Error Code : %d", WSAGetLastError());
				free(newSocket);
				return NULL;
			}
			if (ioctlsocket(newSocket->fd, FIONBIO, &on) < 0)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "ioctl() failed.  Error Code : %d", WSAGetLastError());
				UDBSocket_close(newSocket);
				return NULL;
			}
			memset((char*) &newSocket->si_other, 0, sizeof(newSocket->si_other));
			newSocket->si_other.sin_family = AF_INET;
			newSocket->si_other.sin_port = htons(newSocket->UDP_port);
			newSocket->si_other.sin_addr.S_un.S_addr = inet_addr(UDP_host);

			UDBSocket_write(newSocket, (unsigned char*)"", 0); // Initiate connection
			break;
		}
		case UDBSocketUDPServer:
		{
			struct sockaddr_in si_me;
			u_long on = 1;

			if (!hasInitializedWSA)
			{
				if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
				{
					snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "WSAStartup Failed. Error Code : %d", WSAGetLastError());
					return NULL;
				}
				hasInitializedWSA = 1;
			}
			if ((newSocket->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "socket() Error Code : %d", WSAGetLastError());
				free(newSocket);
				return NULL;
			}
			if (ioctlsocket(newSocket->fd, FIONBIO, &on) < 0)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "ioctl() Error Code : %d", WSAGetLastError());
				UDBSocket_close(newSocket);
				return NULL;
			}
			newSocket->si_other.sin_family = AF_INET;
			memset((char*) &si_me, 0, sizeof(si_me));
			si_me.sin_family = AF_INET;
			si_me.sin_port = htons(newSocket->UDP_port);
			si_me.sin_addr.s_addr = htonl(INADDR_ANY);
			if (bind(newSocket->fd, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "bind() Error Code : %d", WSAGetLastError());
				UDBSocket_close(newSocket);
				return NULL;
			}
			break;
		}
		case UDBSocketSerial:
		{
			DCB Dcb;
			COMMTIMEOUTS CommTimeouts;
			DWORD dwRetFlag;

			if (newSocket->hComms == 0)
			{
				char port[512]; // sketchy, but should be plenty long
				strcpy(port, "\\\\.\\");
				strncpy(port+strlen(port), newSocket->serial_port, 512-6);
				newSocket->hComms = CreateFile(port,
				    GENERIC_READ | GENERIC_WRITE,
				    0,
				    NULL,
				    OPEN_EXISTING,
				    FILE_ATTRIBUTE_NORMAL,// | FILE_FLAG_RANDOM_ACCESS,
				    NULL);
				
				if (newSocket->hComms == INVALID_HANDLE_VALUE)
				{
					//sprintf(ErrorString, "Could not open comm port");
					//ShowMessage(ErrorString);
					//LoggingFile.mLogFile << "Could not open Com Port";
					//LoggingFile.mLogFile << endl;
					snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "Could not open comm port");
					UDBSocket_close(newSocket);
					return NULL;
				}
				else
				{
					dwRetFlag = GetCommState(newSocket->hComms, &Dcb);
					if (!dwRetFlag)
					{
						//sprintf(ErrorString, "GetCommState Error = %d", GetLastError());
						//ShowMessage(ErrorString);
						snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "GetCommState Error = %d", GetLastError());
						UDBSocket_close(newSocket);
						return NULL;
					}
					Dcb.DCBlength = sizeof(Dcb);
					Dcb.BaudRate = newSocket->serial_baud;
					Dcb.ByteSize = 8;
					Dcb.Parity = NOPARITY;
					Dcb.StopBits = ONESTOPBIT;
					Dcb.fTXContinueOnXoff = true;
					Dcb.fOutxCtsFlow = false;                 // disable CTS output flow control
					Dcb.fOutxDsrFlow = false;                 // disable DSR output flow control
					Dcb.fDtrControl = DTR_CONTROL_DISABLE;    // DTR_CONTROL_HANDSHAKE  /*DTR_CONTROL_DISABLE DTR_CONTROL_ENABLE*/;
					Dcb.fDsrSensitivity = false;              // enable DSR sensitivity
					Dcb.fOutX = false;                        // disable XON/XOFF out flow control
					Dcb.fInX = false;                         // disable XON/XOFF in flow control
					Dcb.fErrorChar = false;                   // disable error replacement
					Dcb.fNull = false;                        // disable null stripping
					Dcb.fRtsControl = RTS_CONTROL_DISABLE;    // RTS_CONTROL_HANDSHAKE	  /* RTS_CONTROL_ENABLE  RTS_CONTROL_DISABLE*/;   //  enable RTS line
					Dcb.fAbortOnError = true;                 // don't abort reads/writes on error

					dwRetFlag = SetCommState(newSocket->hComms, &Dcb);
					if (!dwRetFlag)
					{
						//sprintf(ErrorString, "SetCommState Error = %d", GetLastError());
						//ShowMessage(ErrorString);
						snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "SetCommState Error = %d", GetLastError());
						UDBSocket_close(newSocket);
						return NULL;
					}
					dwRetFlag = GetCommTimeouts(newSocket->hComms, &CommTimeouts);
					if (!dwRetFlag)
					{
						//sprintf(ErrorString, "GetCommTimeouts Error = %d", GetLastError());
						//ShowMessage(ErrorString);
						snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "GetCommTimeouts Error = %d", GetLastError());
						UDBSocket_close(newSocket);
						return NULL;
					}
					CommTimeouts.ReadIntervalTimeout         = MAXDWORD;    //Don't use interval timeouts
					CommTimeouts.ReadTotalTimeoutMultiplier  = 0;           //Don't use multipliers
					CommTimeouts.ReadTotalTimeoutConstant    = 0;           //150ms total read timeout
					CommTimeouts.WriteTotalTimeoutMultiplier = 0;           //Don't use multipliers
					CommTimeouts.WriteTotalTimeoutConstant   = 0;           //2200ms total write timeout
					
					dwRetFlag = SetCommTimeouts(newSocket->hComms, &CommTimeouts);
					if (!dwRetFlag)
					{
						//sprintf(ErrorString, "SetCommTimeouts Error = %d", GetLastError());
						//ShowMessage(ErrorString);
						snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "SetCommTimeouts Error = %d", GetLastError());
						UDBSocket_close(newSocket);
						return NULL;
					}
				}
			}
			else
			{
				//ShowMessage("Comm port already open");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "Com Port already open");
				UDBSocket_close(newSocket);
				return NULL;
			}
			break;
		}
		default:
			break;
	}
	return newSocket;
}
Ejemplo n.º 2
0
UDBSocket UDBSocket_init(UDBSocketType type, uint16_t UDP_port, char* UDP_host, char* serial_port, long serial_baud)
{
#if (LIN == 1)
	speed_t BAUD;
#endif
	UDBSocket newSocket = (UDBSocket)malloc(sizeof(UDBSocket_t));
	if (!newSocket)
	{
		return NULL;
	}
	memset((char*)newSocket, 0, sizeof(UDBSocket_t));
	newSocket->type = type;
	newSocket->UDP_port = UDP_port;
	newSocket->UDP_host = (UDP_host) ? strdup(UDP_host) : NULL;
	newSocket->serial_port = (serial_port) ? strdup(serial_port) : NULL;
	newSocket->serial_baud = serial_baud;
	
	switch (newSocket->type)
	{
		case UDBSocketStandardInOut:
		{
			SetTermIOs();
			break;
		}
		case UDBSocketUDPClient:
		{
			if ((newSocket->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
			{
				perror("socket() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "socket() failed");
				free(newSocket);
				return NULL;
			}
			int on = 1;
			if (ioctl(newSocket->fd, FIONBIO, (char*)&on) < 0)
			{
				perror("ioctl() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "ioctl() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			memset((char*) &newSocket->si_other, 0, sizeof(newSocket->si_other));
			newSocket->si_other.sin_family = AF_INET;
			newSocket->si_other.sin_port = htons(newSocket->UDP_port);
			if (inet_aton(UDP_host, &newSocket->si_other.sin_addr) == 0)
			{
				fprintf(stderr, "inet_aton() failed\n");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "inet_aton() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			UDBSocket_write(newSocket, (unsigned char*)"", 0); // Initiate connection
			break;
		}
		case UDBSocketUDPServer:
		{
			struct sockaddr_in si_me;

			if ((newSocket->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
			{
				perror("socket() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "socket() failed");
				free(newSocket);
				return NULL;
			}
			int on = 1;
			if (ioctl(newSocket->fd, FIONBIO, (char*)&on) < 0)
			{
				perror("ioctl() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "ioctl() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			newSocket->si_other.sin_family = AF_INET;
			memset((char*) &si_me, 0, sizeof(si_me));
			si_me.sin_family = AF_INET;
			si_me.sin_port = htons(newSocket->UDP_port);
			si_me.sin_addr.s_addr = htonl(INADDR_ANY);
			if (bind(newSocket->fd, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1)
			{
				perror("bind() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "bind() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			break;
		}
		case UDBSocketSerial:
		{
			struct termios  config;

			newSocket->fd = open(newSocket->serial_port, O_RDWR | O_NOCTTY | O_NDELAY);
			if (newSocket->fd == -1) {
				perror("serial open() failed");
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "serial open() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			if (!isatty(newSocket->fd))
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "serial port not a tty");
				UDBSocket_close(newSocket);
				return NULL;
			}
			if (tcgetattr(newSocket->fd, &config) < 0)
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "tcgetattr() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
#if (LIN == 1)
			switch (newSocket->serial_baud)
			{
				case 1152000:
					BAUD = 1152000;
					break;
				case 1000000:
					BAUD = 1000000;
					break;
				case 921600:
					BAUD = 921600;
					break;
				case 576000:
					BAUD = 576000;
					break;
				case 500000:
					BAUD = 500000;
					break;
				case 460800:
					BAUD = 460800;
					break;
				case 230400:
					BAUD = B230400;
					break;
				case 115200:
					BAUD = B115200;
					break;
				case 57600:
					BAUD = B57600;
					break;
				case 38400:
				    BAUD = B38400;
				    break;
				case 19200:
				    BAUD = B19200;
				    break;
				case 9600:
				    BAUD = B9600;
				    break;
				case 4800:
				    BAUD = B4800;
				    break;
				default:
				    BAUD = B38400;
				    break;
			}  //end of switch CommPortSpeed
#endif
			//
			// Input flags - Turn off input processing
			// convert break to null byte, no CR to NL translation,
			// no NL to CR translation, don't mark parity errors or breaks
			// no input parity check, don't strip high bit off,
			// no XON/XOFF software flow control
			//
			config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
			                    INLCR | PARMRK | INPCK | ISTRIP | IXON);
			//
			// Output flags - Turn off output processing
			// no CR to NL translation, no NL to CR-NL translation,
			// no NL to CR translation, no column 0 CR suppression,
			// no Ctrl-D suppression, no fill characters, no case mapping,
			// no local output processing
			//
			// config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
			//                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
			config.c_oflag = 0;
			//
			// No line processing:
			// echo off, echo newline off, canonical mode off,
			// extended input processing off, signal chars off
			//
			config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
			//
			// Turn off character processing
			// clear current char size mask, no parity checking,
			// no output processing, force 8 bit input
			//
			config.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
			config.c_cflag |= CS8;
			//
			// One input byte is enough to return from read()
			// Inter-character timer off
			//
			config.c_cc[VMIN]  = 1;
			config.c_cc[VTIME] = 0;
#if (LIN == 1)
			if (cfsetospeed(&config, BAUD) < 0)
#else
			if (cfsetospeed(&config, newSocket->serial_baud) < 0)
#endif
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "cfsetospeed() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
#if (LIN == 1)
			if (cfsetispeed(&config, BAUD) < 0)
#else
			if (cfsetispeed(&config, newSocket->serial_baud) < 0)
#endif
			{
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "cfsetispeed() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			//
			// Finally, apply the configuration
			//
			if (tcsetattr(newSocket->fd, TCSAFLUSH, &config) < 0) {
				snprintf(UDBSocketLastError, LAST_ERR_BUF_SIZE, "tcsetattr() failed");
				UDBSocket_close(newSocket);
				return NULL;
			}
			break;
		}
		default:
			break;
	}
	return newSocket;
}