/** * @brief Write data to a socket. * @param[in] socket_handle Handle to the socket to write into. * @param[in] packet Data to write. * @param[in] length Length of the data to write. * @param[out] bytes_written Number of bytes written. * @return Result code. */ tSIRF_RESULT SIRF_PAL_NET_Write( tSIRF_SOCKET socket_handle, tSIRF_UINT8 *packet, tSIRF_UINT32 length, tSIRF_UINT32 *bytes_written ) { int result; DEBUGCHK(SIRF_PAL_NET_INVALID_SOCKET != socket_handle); DEBUGCHK(bytes_written); *bytes_written=0; do { result = send( socket_handle, (char*)(packet+*bytes_written), length-*bytes_written, 0); } while ( result<0 && errno==EINTR ); if ( 0 >= result ) { DEBUGMSG(1,(DEBUGTXT("send() failed, errno=%d\n"), errno)); SIRF_PAL_OS_THREAD_Sleep(100); return SIRF_PAL_NET_ERROR; } *bytes_written = result; return SIRF_SUCCESS; } /* SIRF_PAL_NET_Write() */
/** * @brief Read data from a socket. * @param socket_handle[in] Handle to the socket to read from. * @param buffer[out] Buffer to read data into. * @param size[in] Size of the data buffer. * @param bytes_read[out] Number of bytes read. * @return Result code. */ tSIRF_RESULT SIRF_PAL_NET_Read( tSIRF_SOCKET socket_handle, tSIRF_UINT8 *buffer, tSIRF_UINT32 size, tSIRF_UINT32 *bytes_read ) { int result = 0; DEBUGCHK(SIRF_PAL_NET_INVALID_SOCKET != socket_handle); DEBUGCHK(bytes_read); *bytes_read = 0; do { result = recv(socket_handle, (char*)(buffer+*bytes_read), size-*bytes_read, 0); } while ( 0 > result && EINTR == errno ); if ( 0 > result ) { DEBUGMSG(1,(DEBUGTXT("recv() failed, errno=%d, size=%d, *bytes_read=%d\n"), errno, size, *bytes_read)); SIRF_PAL_OS_THREAD_Sleep(100); return SIRF_PAL_NET_ERROR; } *bytes_read = result; return 0 < result ? SIRF_SUCCESS : SIRF_PAL_NET_CONNECTION_CLOSED; } /* SIRF_PAL_NET_Read() */
/** * @brief Registered callback function for failures * * When these errors occur, it indicates some type of critical system failure. * * @param heap The heap object * @param err Error found * @param extra Extra data * */ static tSIRF_VOID GprsMsgQueueHeap_notify(tHeap heap, tHeapError err, unsigned long extra) { (void)extra; #ifndef DEBUG (void) heap; (void) err; #endif DEBUGMSG(1,(DEBUGTXT("gprs msg queue heap error heap %x err %d "), heap, err)); UTIL_Assert(FALSE); }
/** * @brief Bind a socket to the specified address. * @param[in] socket_handle Handle to the socket. * @param[in] name Socket address to bind to. * @return Result code. */ tSIRF_RESULT SIRF_PAL_NET_Bind( tSIRF_SOCKET socket_handle, tSIRF_SOCKADDR *name ) { int result; DEBUGCHK(SIRF_PAL_NET_INVALID_SOCKET != socket_handle&&name); name->reserved_0 = AF_INET; result = bind(socket_handle, (struct sockaddr*)name, sizeof(tSIRF_SOCKADDR)); if (0 != result) { DEBUGMSG(1,(DEBUGTXT("bind() failed, errno=%d\n"), errno)); } return 0==result ? SIRF_SUCCESS : SIRF_PAL_NET_ERROR; } /* SIRF_PAL_NET_Bind() */
/** * @brief Create a socket of the specified type. * @param socket_handle[out] Handle to the socket. * @param socket_type[in] Type of socket to create. * @return Result code. */ tSIRF_RESULT SIRF_PAL_NET_CreateSocket( tSIRF_SOCKET *socket_handle, tSIRF_UINT32 socket_type ) { char opt_c; int result = 0; DEBUGCHK(socket_handle); *socket_handle = (tSIRF_SOCKET)socket(AF_INET, SOCK_STREAM, 0); if (!IsValidSocket(*socket_handle)) { DEBUGMSG(1,(DEBUGTXT("socket() failed, errno=%d\n"), errno)); *socket_handle = SIRF_PAL_NET_INVALID_SOCKET; return SIRF_PAL_NET_ERROR; } /* Set all socket options here: */ switch (socket_type) { case SIRF_PAL_NET_SOCKET_TYPE_BLOCKING: /* Sockets are blocking by default */ break; case SIRF_PAL_NET_SOCKET_TYPE_DEFAULT: { do { result = fcntl( *socket_handle, F_SETFL, O_NONBLOCK ); } while (result!=0 && errno==EINTR); if (0<result) { DEBUGMSG(1,(DEBUGTXT("fcntl() failed, errno=%d\n"), errno)); } break; } default: return SIRF_PAL_NET_ERROR; } opt_c = 1; result = setsockopt(*socket_handle, SOL_SOCKET, SO_REUSEADDR, (char*)&opt_c, sizeof(opt_c)); if (0!=result) { DEBUGMSG(1,(DEBUGTXT("setsockopt() failed, errno=%d\n"), errno)); SIRF_PAL_NET_CloseSocket(*socket_handle); return SIRF_PAL_NET_ERROR; } opt_c = 1; result = setsockopt(*socket_handle, SOL_SOCKET, SO_DONTLINGER, (char*)&opt_c, sizeof(opt_c)); if (0!=result) { DEBUGMSG(1,(DEBUGTXT("setsockopt() failed, errno=%d\n"), errno)); SIRF_PAL_NET_CloseSocket(*socket_handle); return SIRF_PAL_NET_ERROR; } opt_c = 1; result = setsockopt(*socket_handle, IPPROTO_TCP, TCP_NODELAY, (char*)&opt_c, sizeof(opt_c)); if (0!=result) { DEBUGMSG(1,(DEBUGTXT("setsockopt() failed, errno=%d\n"), errno)); SIRF_PAL_NET_CloseSocket(*socket_handle); return SIRF_PAL_NET_ERROR; } return SIRF_SUCCESS; } /* SIRF_PAL_NET_CreateSocket() */
/** * @brief Connect to the specified address/port. * @param[in] socket_handle Socket handle. * @param[in] addr Address to connect to. * @param[in] port Port to connect to. * @return Result code. */ tSIRF_RESULT SIRF_PAL_NET_Connect( tSIRF_SOCKET socket_handle, tSIRF_CHAR *addr, tSIRF_UINT16 port, tSIRF_UINT32 security ) { unsigned long ** p_addr; int result = 0; tSIRF_SOCKADDR sockaddr; struct hostent * host_addrs; DEBUGCHK((SIRF_PAL_NET_INVALID_SOCKET != socket_handle) && addr); if (SIRF_PAL_NET_SECURITY_NONE != security) { return SIRF_PAL_NET_SECURITY_NOT_SUPPORTED; } /* convert from dotted notation to sockaddr: */ { /* Use TCP if DNS lookup needed */ sethostent(1); do { host_addrs = gethostbyname( addr ); } while (NULL == host_addrs && TRY_AGAIN == h_errno); endhostent(); if (NULL == host_addrs) return SIRF_PAL_NET_ERROR; } p_addr = (unsigned long **)host_addrs->h_addr_list; do { sockaddr.reserved_0 = AF_INET; sockaddr.sin_addr = **p_addr++; sockaddr.sin_port = htons(port); do { result = connect(socket_handle, (struct sockaddr*)&sockaddr, sizeof(tSIRF_SOCKADDR)); if (0 != result) { if (EINPROGRESS==errno || EWOULDBLOCK==errno) { return SIRF_SUCCESS;/* connection request sent, waiting for reply */ } if ( EINTR == errno ) { continue; } else { DEBUGMSG(1,(DEBUGTXT("connect() to IP %s failed, errno=%d trying next\n"), inet_ntoa(sockaddr), errno)); break; } } } while ( 0 != result ); } while ((0 != *p_addr) && (0 != result)); if (0 != result) { DEBUGMSG(1,(DEBUGTXT("connect() failed, errno\n"))); return SIRF_PAL_NET_ERROR; } return SIRF_SUCCESS; } /* SIRF_PAL_NET_Connect() */