Roy van Dam / NetworkAPI

Dependents:   NetRelais TCP_Client_Example TCP_Server_Example UDP_Server_Example ... more

Revision:
2:e283a0062097
Parent:
1:6956f6f96fef
Child:
3:d30db8752485
--- a/udp/socket.cpp	Tue Jul 17 15:19:47 2012 +0000
+++ b/udp/socket.cpp	Tue Jul 17 18:31:22 2012 +0000
@@ -29,41 +29,123 @@
 int
 Socket::open()
 {
-    return 0;
-}
-
-int
-Socket::close()
-{
+    // Check socket status
+    if (this->_status != Socket::Closed) {
+        return -1;
+    }
+    
+    // Open socket
+    this->_socket = ::socket(AF_INET, SOCK_DGRAM, 0);
+    if (this->_socket < 0) {
+        return -1;
+    }
+    
+    // Update status and return
+    this->_status = Socket::Open;
     return 0;
 }
 
 int
 Socket::bind(int port)
 {
-    return 0;
-}
+    // Check socket status
+    if (this->_status != Socket::Open) {
+        return -1;
+    }
+    
+    // Update local endpoint and create native
+    struct sockaddr_in native_endpoint;
+    this->_local_endpoint.setAddress(ip::Address(ip::Address::Any));
+    this->_local_endpoint.setPort(port);
+    this->_local_endpoint.toNative(&native_endpoint);
+    
+    // Bind socket to endpoint
+    if (::bind(this->_socket,
+        (const struct sockaddr *)&native_endpoint,
+        sizeof(native_endpoint)) < 0)
+    {
+        return -1;
+    }
 
-int
-Socket::send(void *data, size_t size, ip::Endpoint &endpoint)
-{
     return 0;
 }
 
 int
 Socket::send(void *data, size_t size, ip::Address &address, int port)
 {
-    return 0;
+    ip::Endpoint endpoint(address, port);
+    return this->send(data, size, endpoint);
+}
+
+int
+Socket::send(void *data, size_t size, ip::Endpoint &endpoint)
+{
+    // Check data buffer and size
+    if (data == NULL || size == 0) {
+        return -1;
+    }
+
+    // Check socket status
+    if (this->_status != Socket::Open) {
+        return -1;
+    }
+    
+    // Create native endpoint
+    struct sockaddr_in native_endpoint;
+    endpoint.toNative(&native_endpoint);
+    
+    // Update status
+    this->_status = Socket::Sending;
+    
+    // Try to write the specified amount of bytes.
+    int bytes_written = ::sendto(this->_socket, data, size, 0,
+        (const struct sockaddr *)&native_endpoint, sizeof(native_endpoint));
+    
+    // Update status
+    this->_status = Socket::Open;
+    
+    // Return the result.
+    return bytes_written;
 }
 
 int
 Socket::reveive(void *data, size_t max_size, ip::Endpoint &endpoint)
 {
-    return 0;
-}
+    // Check data buffer and size
+    if (data == NULL || max_size == 0) {
+        return -1;
+    }
+
+    // Check socket status
+    if (this->_status != Socket::Open) {
+        return -1;
+    }
 
-int
-Socket::reveive(void *data, size_t max_size, ip::Address &address, int port)
-{
-    return 0;
+    // Create native endpoint
+    int native_endpoint_size;
+    struct sockaddr_in native_endpoint;
+    std::memset(&native_endpoint, 0, sizeof(native_endpoint));
+    
+    // Update status
+    this->_status = Socket::Receiving;
+    
+    // Try to read a packet from the socket.
+    int bytes_read = ::recvfrom(this->_socket, data, max_size, 0,
+        (struct sockaddr*)&native_endpoint, (u32_t *)&native_endpoint_size);
+    
+    // Update status and return
+    this->_status = Socket::Open;
+    
+    // Did we succeed? 
+    if (bytes_read < 0) {
+        return -1;
+    }
+    
+    // Copy native endpoint
+    if (native_endpoint_size == sizeof(native_endpoint)) {
+        endpoint.fromNative(&native_endpoint);
+    }
+    
+    // Return bytes read
+    return bytes_read;
 }