Preliminary main mbed library for nexpaq development
Diff: features/net/network-socket/Socket.cpp
- Revision:
- 0:6c56fb4bc5f0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/features/net/network-socket/Socket.cpp Fri Nov 04 20:27:58 2016 +0000 @@ -0,0 +1,158 @@ +/* Socket + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Socket.h" +#include "mbed.h" + +Socket::Socket() + : _stack(0) + , _socket(0) + , _timeout(osWaitForever) +{ +} + +int Socket::open(NetworkStack *stack) +{ + _lock.lock(); + + if (_stack != NULL || stack == NULL) { + _lock.unlock(); + return NSAPI_ERROR_PARAMETER; + } + _stack = stack; + + nsapi_socket_t socket; + int err = _stack->socket_open(&socket, get_proto()); + if (err) { + _lock.unlock(); + return err; + } + + _socket = socket; + _event.attach(this, &Socket::event); + _stack->socket_attach(_socket, Callback<void()>::thunk, &_event); + + _lock.unlock(); + return 0; +} + +int Socket::close() +{ + _lock.lock(); + + int ret = 0; + if (_socket) { + _stack->socket_attach(_socket, 0, 0); + nsapi_socket_t socket = _socket; + _socket = 0; + ret = _stack->socket_close(socket); + } + + // Wakeup anything in a blocking operation + // on this socket + event(); + + _lock.unlock(); + return ret; +} + +int Socket::bind(uint16_t port) +{ + // Underlying bind is thread safe + SocketAddress addr(0, port); + return bind(addr); +} + +int Socket::bind(const char *address, uint16_t port) +{ + // Underlying bind is thread safe + SocketAddress addr(address, port); + return bind(addr); +} + +int Socket::bind(const SocketAddress &address) +{ + _lock.lock(); + int ret; + + if (!_socket) { + ret = NSAPI_ERROR_NO_SOCKET; + } else { + ret = _stack->socket_bind(_socket, address); + } + + _lock.unlock(); + return ret; +} + +void Socket::set_blocking(bool blocking) +{ + // Socket::set_timeout is thread safe + set_timeout(blocking ? -1 : 0); +} + +void Socket::set_timeout(int timeout) +{ + _lock.lock(); + + if (timeout >= 0) { + _timeout = (uint32_t)timeout; + } else { + _timeout = osWaitForever; + } + + _lock.unlock(); +} + +int Socket::setsockopt(int level, int optname, const void *optval, unsigned optlen) +{ + _lock.lock(); + int ret; + + if (!_socket) { + ret = NSAPI_ERROR_NO_SOCKET; + } else { + ret = _stack->setsockopt(_socket, level, optname, optval, optlen); + } + + _lock.unlock(); + return ret; +} + +int Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen) +{ + _lock.lock(); + int ret; + + if (!_socket) { + ret = NSAPI_ERROR_NO_SOCKET; + } else { + ret = _stack->getsockopt(_socket, level, optname, optval, optlen); + } + + _lock.unlock(); + return ret; + +} + +void Socket::attach(Callback<void()> callback) +{ + _lock.lock(); + + _callback = callback; + + _lock.unlock(); +}