BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:47:08 2018 +0000
Revision:
1:9c5af431a1f1
sdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gustavatmel 1:9c5af431a1f1 1 /* Socket
gustavatmel 1:9c5af431a1f1 2 * Copyright (c) 2015 ARM Limited
gustavatmel 1:9c5af431a1f1 3 *
gustavatmel 1:9c5af431a1f1 4 * Licensed under the Apache License, Version 2.0 (the "License");
gustavatmel 1:9c5af431a1f1 5 * you may not use this file except in compliance with the License.
gustavatmel 1:9c5af431a1f1 6 * You may obtain a copy of the License at
gustavatmel 1:9c5af431a1f1 7 *
gustavatmel 1:9c5af431a1f1 8 * http://www.apache.org/licenses/LICENSE-2.0
gustavatmel 1:9c5af431a1f1 9 *
gustavatmel 1:9c5af431a1f1 10 * Unless required by applicable law or agreed to in writing, software
gustavatmel 1:9c5af431a1f1 11 * distributed under the License is distributed on an "AS IS" BASIS,
gustavatmel 1:9c5af431a1f1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
gustavatmel 1:9c5af431a1f1 13 * See the License for the specific language governing permissions and
gustavatmel 1:9c5af431a1f1 14 * limitations under the License.
gustavatmel 1:9c5af431a1f1 15 */
gustavatmel 1:9c5af431a1f1 16
gustavatmel 1:9c5af431a1f1 17 #include "Socket.h"
gustavatmel 1:9c5af431a1f1 18 #include "mbed.h"
gustavatmel 1:9c5af431a1f1 19
gustavatmel 1:9c5af431a1f1 20 Socket::Socket()
gustavatmel 1:9c5af431a1f1 21 : _stack(0)
gustavatmel 1:9c5af431a1f1 22 , _socket(0)
gustavatmel 1:9c5af431a1f1 23 , _timeout(osWaitForever)
gustavatmel 1:9c5af431a1f1 24 {
gustavatmel 1:9c5af431a1f1 25 }
gustavatmel 1:9c5af431a1f1 26
gustavatmel 1:9c5af431a1f1 27 nsapi_error_t Socket::open(NetworkStack *stack)
gustavatmel 1:9c5af431a1f1 28 {
gustavatmel 1:9c5af431a1f1 29 _lock.lock();
gustavatmel 1:9c5af431a1f1 30
gustavatmel 1:9c5af431a1f1 31 if (_stack != NULL || stack == NULL) {
gustavatmel 1:9c5af431a1f1 32 _lock.unlock();
gustavatmel 1:9c5af431a1f1 33 return NSAPI_ERROR_PARAMETER;
gustavatmel 1:9c5af431a1f1 34 }
gustavatmel 1:9c5af431a1f1 35 _stack = stack;
gustavatmel 1:9c5af431a1f1 36
gustavatmel 1:9c5af431a1f1 37 nsapi_socket_t socket;
gustavatmel 1:9c5af431a1f1 38 nsapi_error_t err = _stack->socket_open(&socket, get_proto());
gustavatmel 1:9c5af431a1f1 39 if (err) {
gustavatmel 1:9c5af431a1f1 40 _lock.unlock();
gustavatmel 1:9c5af431a1f1 41 return err;
gustavatmel 1:9c5af431a1f1 42 }
gustavatmel 1:9c5af431a1f1 43
gustavatmel 1:9c5af431a1f1 44 _socket = socket;
gustavatmel 1:9c5af431a1f1 45 _event = callback(this, &Socket::event);
gustavatmel 1:9c5af431a1f1 46 _stack->socket_attach(_socket, Callback<void()>::thunk, &_event);
gustavatmel 1:9c5af431a1f1 47
gustavatmel 1:9c5af431a1f1 48 _lock.unlock();
gustavatmel 1:9c5af431a1f1 49 return NSAPI_ERROR_OK;
gustavatmel 1:9c5af431a1f1 50 }
gustavatmel 1:9c5af431a1f1 51
gustavatmel 1:9c5af431a1f1 52 nsapi_error_t Socket::close()
gustavatmel 1:9c5af431a1f1 53 {
gustavatmel 1:9c5af431a1f1 54 _lock.lock();
gustavatmel 1:9c5af431a1f1 55
gustavatmel 1:9c5af431a1f1 56 nsapi_error_t ret = NSAPI_ERROR_OK;
gustavatmel 1:9c5af431a1f1 57 if (_socket) {
gustavatmel 1:9c5af431a1f1 58 _stack->socket_attach(_socket, 0, 0);
gustavatmel 1:9c5af431a1f1 59 nsapi_socket_t socket = _socket;
gustavatmel 1:9c5af431a1f1 60 _socket = 0;
gustavatmel 1:9c5af431a1f1 61 ret = _stack->socket_close(socket);
gustavatmel 1:9c5af431a1f1 62 }
gustavatmel 1:9c5af431a1f1 63 _stack = 0;
gustavatmel 1:9c5af431a1f1 64
gustavatmel 1:9c5af431a1f1 65 // Wakeup anything in a blocking operation
gustavatmel 1:9c5af431a1f1 66 // on this socket
gustavatmel 1:9c5af431a1f1 67 event();
gustavatmel 1:9c5af431a1f1 68
gustavatmel 1:9c5af431a1f1 69 _lock.unlock();
gustavatmel 1:9c5af431a1f1 70 return ret;
gustavatmel 1:9c5af431a1f1 71 }
gustavatmel 1:9c5af431a1f1 72
gustavatmel 1:9c5af431a1f1 73 int Socket::modify_multicast_group(const SocketAddress &address, nsapi_socket_option_t socketopt)
gustavatmel 1:9c5af431a1f1 74 {
gustavatmel 1:9c5af431a1f1 75 nsapi_ip_mreq_t mreq;
gustavatmel 1:9c5af431a1f1 76
gustavatmel 1:9c5af431a1f1 77 // Set up group address
gustavatmel 1:9c5af431a1f1 78 mreq.imr_multiaddr = address.get_addr();
gustavatmel 1:9c5af431a1f1 79 mreq.imr_interface = nsapi_addr_t(); // Default address, NSAPI_UNSPEC
gustavatmel 1:9c5af431a1f1 80
gustavatmel 1:9c5af431a1f1 81 return this->setsockopt(NSAPI_SOCKET, socketopt, &mreq, sizeof(mreq));
gustavatmel 1:9c5af431a1f1 82 }
gustavatmel 1:9c5af431a1f1 83
gustavatmel 1:9c5af431a1f1 84 int Socket::join_multicast_group(const SocketAddress &address)
gustavatmel 1:9c5af431a1f1 85 {
gustavatmel 1:9c5af431a1f1 86 return modify_multicast_group(address, NSAPI_ADD_MEMBERSHIP);
gustavatmel 1:9c5af431a1f1 87 }
gustavatmel 1:9c5af431a1f1 88
gustavatmel 1:9c5af431a1f1 89 int Socket::leave_multicast_group(const SocketAddress &address)
gustavatmel 1:9c5af431a1f1 90 {
gustavatmel 1:9c5af431a1f1 91 return modify_multicast_group(address, NSAPI_DROP_MEMBERSHIP);
gustavatmel 1:9c5af431a1f1 92 }
gustavatmel 1:9c5af431a1f1 93
gustavatmel 1:9c5af431a1f1 94
gustavatmel 1:9c5af431a1f1 95 nsapi_error_t Socket::bind(uint16_t port)
gustavatmel 1:9c5af431a1f1 96 {
gustavatmel 1:9c5af431a1f1 97 // Underlying bind is thread safe
gustavatmel 1:9c5af431a1f1 98 SocketAddress addr(0, port);
gustavatmel 1:9c5af431a1f1 99 return bind(addr);
gustavatmel 1:9c5af431a1f1 100 }
gustavatmel 1:9c5af431a1f1 101
gustavatmel 1:9c5af431a1f1 102 nsapi_error_t Socket::bind(const char *address, uint16_t port)
gustavatmel 1:9c5af431a1f1 103 {
gustavatmel 1:9c5af431a1f1 104 // Underlying bind is thread safe
gustavatmel 1:9c5af431a1f1 105 SocketAddress addr(address, port);
gustavatmel 1:9c5af431a1f1 106 return bind(addr);
gustavatmel 1:9c5af431a1f1 107 }
gustavatmel 1:9c5af431a1f1 108
gustavatmel 1:9c5af431a1f1 109 nsapi_error_t Socket::bind(const SocketAddress &address)
gustavatmel 1:9c5af431a1f1 110 {
gustavatmel 1:9c5af431a1f1 111 _lock.lock();
gustavatmel 1:9c5af431a1f1 112 nsapi_error_t ret;
gustavatmel 1:9c5af431a1f1 113
gustavatmel 1:9c5af431a1f1 114 if (!_socket) {
gustavatmel 1:9c5af431a1f1 115 ret = NSAPI_ERROR_NO_SOCKET;
gustavatmel 1:9c5af431a1f1 116 } else {
gustavatmel 1:9c5af431a1f1 117 ret = _stack->socket_bind(_socket, address);
gustavatmel 1:9c5af431a1f1 118 }
gustavatmel 1:9c5af431a1f1 119
gustavatmel 1:9c5af431a1f1 120 _lock.unlock();
gustavatmel 1:9c5af431a1f1 121 return ret;
gustavatmel 1:9c5af431a1f1 122 }
gustavatmel 1:9c5af431a1f1 123
gustavatmel 1:9c5af431a1f1 124 void Socket::set_blocking(bool blocking)
gustavatmel 1:9c5af431a1f1 125 {
gustavatmel 1:9c5af431a1f1 126 // Socket::set_timeout is thread safe
gustavatmel 1:9c5af431a1f1 127 set_timeout(blocking ? -1 : 0);
gustavatmel 1:9c5af431a1f1 128 }
gustavatmel 1:9c5af431a1f1 129
gustavatmel 1:9c5af431a1f1 130 void Socket::set_timeout(int timeout)
gustavatmel 1:9c5af431a1f1 131 {
gustavatmel 1:9c5af431a1f1 132 _lock.lock();
gustavatmel 1:9c5af431a1f1 133
gustavatmel 1:9c5af431a1f1 134 if (timeout >= 0) {
gustavatmel 1:9c5af431a1f1 135 _timeout = (uint32_t)timeout;
gustavatmel 1:9c5af431a1f1 136 } else {
gustavatmel 1:9c5af431a1f1 137 _timeout = osWaitForever;
gustavatmel 1:9c5af431a1f1 138 }
gustavatmel 1:9c5af431a1f1 139
gustavatmel 1:9c5af431a1f1 140 _lock.unlock();
gustavatmel 1:9c5af431a1f1 141 }
gustavatmel 1:9c5af431a1f1 142
gustavatmel 1:9c5af431a1f1 143 nsapi_error_t Socket::setsockopt(int level, int optname, const void *optval, unsigned optlen)
gustavatmel 1:9c5af431a1f1 144 {
gustavatmel 1:9c5af431a1f1 145 _lock.lock();
gustavatmel 1:9c5af431a1f1 146 nsapi_error_t ret;
gustavatmel 1:9c5af431a1f1 147
gustavatmel 1:9c5af431a1f1 148 if (!_socket) {
gustavatmel 1:9c5af431a1f1 149 ret = NSAPI_ERROR_NO_SOCKET;
gustavatmel 1:9c5af431a1f1 150 } else {
gustavatmel 1:9c5af431a1f1 151 ret = _stack->setsockopt(_socket, level, optname, optval, optlen);
gustavatmel 1:9c5af431a1f1 152 }
gustavatmel 1:9c5af431a1f1 153
gustavatmel 1:9c5af431a1f1 154 _lock.unlock();
gustavatmel 1:9c5af431a1f1 155 return ret;
gustavatmel 1:9c5af431a1f1 156 }
gustavatmel 1:9c5af431a1f1 157
gustavatmel 1:9c5af431a1f1 158 nsapi_error_t Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen)
gustavatmel 1:9c5af431a1f1 159 {
gustavatmel 1:9c5af431a1f1 160 _lock.lock();
gustavatmel 1:9c5af431a1f1 161 nsapi_error_t ret;
gustavatmel 1:9c5af431a1f1 162
gustavatmel 1:9c5af431a1f1 163 if (!_socket) {
gustavatmel 1:9c5af431a1f1 164 ret = NSAPI_ERROR_NO_SOCKET;
gustavatmel 1:9c5af431a1f1 165 } else {
gustavatmel 1:9c5af431a1f1 166 ret = _stack->getsockopt(_socket, level, optname, optval, optlen);
gustavatmel 1:9c5af431a1f1 167 }
gustavatmel 1:9c5af431a1f1 168
gustavatmel 1:9c5af431a1f1 169 _lock.unlock();
gustavatmel 1:9c5af431a1f1 170 return ret;
gustavatmel 1:9c5af431a1f1 171
gustavatmel 1:9c5af431a1f1 172 }
gustavatmel 1:9c5af431a1f1 173
gustavatmel 1:9c5af431a1f1 174 void Socket::sigio(Callback<void()> callback)
gustavatmel 1:9c5af431a1f1 175 {
gustavatmel 1:9c5af431a1f1 176 _lock.lock();
gustavatmel 1:9c5af431a1f1 177 _callback = callback;
gustavatmel 1:9c5af431a1f1 178 _lock.unlock();
gustavatmel 1:9c5af431a1f1 179 }
gustavatmel 1:9c5af431a1f1 180
gustavatmel 1:9c5af431a1f1 181 void Socket::attach(Callback<void()> callback)
gustavatmel 1:9c5af431a1f1 182 {
gustavatmel 1:9c5af431a1f1 183 sigio(callback);
gustavatmel 1:9c5af431a1f1 184 }