示例#1
0
int GSMClient::read(uint8_t *buf, size_t size)
{
	return internalRead(buf, size, false);
}
GpioState GpioPlateformImplementation::read()
{

    return internalRead();
}
示例#3
0
int GSMClient::readln(uint8_t *buf, size_t size)
{
	return internalRead(buf, size, true);
}
示例#4
0
void Connection::executeNetwork()
{
	switch(m_state){
	case STATE_INIT:
	{
		//Resolve host
		m_ip = inet_addr(m_host.c_str());
		if(m_ip == INADDR_NONE){
			struct hostent* hp = gethostbyname(m_host.c_str());
			if(hp != NULL){
				if(hp->h_addrtype == AF_INET){
					//only are supported ipv4 addr
					m_ip = *(uint32_t*)hp->h_addr_list[0];
				}
				else{
					closeConnectionError(ERROR_WRONG_HOST_ADDR_TYPE);
					return;
				}
			}
			else{
				closeConnectionError(ERROR_CANNOT_RESOLVE_HOST);
				return;
			}
		}
		//Create a TCP socket
		m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		#ifdef WIN32
		if(m_socket == INVALID_SOCKET){
            closeConnectionError(ERROR_CANNOT_CREATE_SOCKET);
			return;
		}
		#else
		if(m_socket <= 0){
			m_socket = INVALID_SOCKET;
            closeConnectionError(ERROR_CANNOT_CREATE_SOCKET);
			return;
		}
		#endif


		//Set non-blocking socket
		#ifdef WIN32
		unsigned long mode = 1;
		if(ioctlsocket(m_socket, FIONBIO, &mode) == SOCKET_ERROR){
			closeConnectionError(ERROR_CANNOT_SET_NOBLOCKING_SOCKET);
			return;
		}
		#else
		if(fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1){
			closeConnectionError(ERROR_CANNOT_SET_NOBLOCKING_SOCKET);
			return;
		}
		#endif

		//Reset traffic counter
		m_sentBytes = 0;
		m_recvBytes = 0;

		//And connect
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = m_ip;
		addr.sin_port = htons(m_port);

		int ret = connect(m_socket, (sockaddr*)&addr, sizeof(addr));
		if(ret == SOCKET_ERROR && getSocketError() != CONNECT_WOULD_BLOCK){
			closeConnectionError(ERROR_CANNOT_CONNECT);
			return;
		}
		else if(ret == 0){
			//connection succeeds
			m_state = STATE_CONNECTED;
		}
		else{
			//waiting non blocking connect
			m_state = STATE_CONNECTING;
			m_ticks = SDL_GetTicks();
		}

		break;
	}
	case STATE_CONNECTING:
	{
		//Check socket state
		timeval tv =  {0, 0}; //non-blocking select
		fd_set write_set;
		FD_ZERO(&write_set);
		FD_SET(m_socket, &write_set);

		int ret = select(m_socket + 1, NULL, &write_set, NULL, &tv);
		if(ret == 0){
			//time expired, socket not connected yet
			if(SDL_GetTicks() - m_ticks > 20*1000){
				//waiting 20 seconds? -> timeout
				closeConnectionError(ERROR_CONNECT_TIMEOUT);
			}
		}
		else if(ret == 1 && FD_ISSET(m_socket, &write_set)){
#ifndef WINCE
			//Check if it was a successful connection
			int optError;
			optlen_t optErrorLen = sizeof(optError);
			int ret = getsockopt(m_socket, SOL_SOCKET, SO_ERROR, (opt_t*)&optError, &optErrorLen);
			if(ret != SOCKET_ERROR && optError == 0){
				//connection succeeded
				m_state = STATE_CONNECTED;

				// record starts now
				if(g_recordfilename.size())
				{
                    m_recordstart=SDL_GetTicks();
                    m_recordfile=yatc_fopen(g_recordfilename.c_str(),"wb");
				}

				//raise onConnect event
                m_protocol->onConnect();
			}
			else if(ret != SOCKET_ERROR && optError != 0){
				//connection failed
				closeConnectionError(ERROR_UNSUCCESSFUL_CONNECTION);
			}
			else{
				//call to getsockopt failed
				closeConnectionError(ERROR_GETSOCKTOPT_FAIL);
			}
#else
			// Since Windows Mobile 2003 (WINCE4.20) seems to set 120 in WSAGetLastError() which stands for something
			// like CALLNOTIMPLEMENTED we'll just stub this to successful connection and pray it works ;)
			DEBUGPRINT(DEBUGPRINT_LEVEL_OBLIGATORY, DEBUGPRINT_NORMAL, "WINCE Connection\n");
			m_state = STATE_CONNECTED;
			m_protocol->onConnect();
#endif
		}
		else if(ret == SOCKET_ERROR){
			//select failed
			closeConnectionError(ERROR_SELECT_FAIL_CONNECTING);
		}
		else{
			//should not reach this point
			closeConnectionError(ERROR_UNEXPECTED_SELECT_RETURN_VALUE);
		}

		break;
	}
	case STATE_CONNECTED:
	{
		//Try to read messages
		while(m_state == STATE_CONNECTED && getPendingInput() > 0){
			switch(m_readState){
				case READING_SIZE:
				{
					int ret = internalRead(2, true);
					if(ret != 2){
						checkSocketReadState();
						return;
					}
					if(!m_inputMessage.getU16(m_msgSize)){
						printf("Failed reading msg size\n");
						closeConnectionError(ERROR_UNEXPECTED_RECV_ERROR);
						return;
					}
					if(m_msgSize > NETWORK_MESSAGE_SIZE){
						closeConnectionError(ERROR_TOO_BIG_MESSAGE);
						return;
					}
				}
				case READING_CHECKSUM: {
					if(m_checksumEnable){
						m_readState = READING_CHECKSUM;
						int ret = internalRead(4, true);
						if(ret != 4){
							checkSocketReadState();
							return;
						}
						uint32_t checksum;
						if(!m_inputMessage.getU32(checksum)){
							printf("Failed reading checksum\n");
							closeConnectionError(ERROR_UNEXPECTED_RECV_ERROR);
							return;
						} else {
							m_msgSize-=4;
							m_readState = READING_MESSAGE;
						}
					} else
						m_readState = READING_MESSAGE;
				}
				case READING_MESSAGE:
				{
					int ret = internalRead(m_msgSize, false);
					if(ret <= 0){
						checkSocketReadState();
						return;
					}
					else if(ret != m_msgSize){
						m_msgSize -= ret;
						checkSocketReadState();

						return;
					}

					//decrypt incoming message if needed
					if(m_cryptoEnable && m_crypto){
						if(!m_crypto->decrypt(m_inputMessage)){
							closeConnectionError(ERROR_DECRYPT_FAIL);
							return;
						}
					} else if(!m_cryptoEnable) {
					    m_inputMessage.setReadPos(2);
					} else {
                        // this is 8.41 specific
                        // data in unencrypted packets is now including unencrypted length,
                        // + encrypted length ... although packet is not encrypted
                        // let's just cut the cr/\p
                        /*uint16_t size = */m_inputMessage.getU16();
					}

					if(m_recordfile)
					{
					    uint32_t timestamp=SDL_GetTicks()-m_recordstart;
					    uint16_t size=m_inputMessage.getReadSize();

					    fwrite(&timestamp, 4, 1, m_recordfile);
					    fwrite(&size,2,1,m_recordfile);
					    fwrite(m_inputMessage.getReadBuffer(), m_inputMessage.getReadSize(), 1, m_recordfile);
                                            fflush(m_recordfile);

					}


					//raise onRecv event
					if(!m_protocol->onRecv(m_inputMessage)){
						closeConnectionError(ERROR_PROTOCOL_ONRECV);
						return;
					}
					//resets input message state
					m_readState = READING_SIZE;
					m_inputMessage.reset();
					break;
				}
			}
		}
		checkSocketReadState();
		break;
	}
	case STATE_CLOSED:
	case STATE_ERROR:
		//nothing to do
		break;
	}
}