Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 /* Socket
nexpaq 0:6c56fb4bc5f0 2 * Copyright (c) 2015 ARM Limited
nexpaq 0:6c56fb4bc5f0 3 *
nexpaq 0:6c56fb4bc5f0 4 * Licensed under the Apache License, Version 2.0 (the "License");
nexpaq 0:6c56fb4bc5f0 5 * you may not use this file except in compliance with the License.
nexpaq 0:6c56fb4bc5f0 6 * You may obtain a copy of the License at
nexpaq 0:6c56fb4bc5f0 7 *
nexpaq 0:6c56fb4bc5f0 8 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 0:6c56fb4bc5f0 9 *
nexpaq 0:6c56fb4bc5f0 10 * Unless required by applicable law or agreed to in writing, software
nexpaq 0:6c56fb4bc5f0 11 * distributed under the License is distributed on an "AS IS" BASIS,
nexpaq 0:6c56fb4bc5f0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 0:6c56fb4bc5f0 13 * See the License for the specific language governing permissions and
nexpaq 0:6c56fb4bc5f0 14 * limitations under the License.
nexpaq 0:6c56fb4bc5f0 15 */
nexpaq 0:6c56fb4bc5f0 16
nexpaq 0:6c56fb4bc5f0 17 #include "TCPServer.h"
nexpaq 0:6c56fb4bc5f0 18 #include "mbed.h"
nexpaq 0:6c56fb4bc5f0 19
nexpaq 0:6c56fb4bc5f0 20 TCPServer::TCPServer()
nexpaq 0:6c56fb4bc5f0 21 : _pending(0), _accept_sem(0)
nexpaq 0:6c56fb4bc5f0 22 {
nexpaq 0:6c56fb4bc5f0 23 }
nexpaq 0:6c56fb4bc5f0 24
nexpaq 0:6c56fb4bc5f0 25 TCPServer::~TCPServer()
nexpaq 0:6c56fb4bc5f0 26 {
nexpaq 0:6c56fb4bc5f0 27 close();
nexpaq 0:6c56fb4bc5f0 28 }
nexpaq 0:6c56fb4bc5f0 29
nexpaq 0:6c56fb4bc5f0 30 nsapi_protocol_t TCPServer::get_proto()
nexpaq 0:6c56fb4bc5f0 31 {
nexpaq 0:6c56fb4bc5f0 32 return NSAPI_TCP;
nexpaq 0:6c56fb4bc5f0 33 }
nexpaq 0:6c56fb4bc5f0 34
nexpaq 0:6c56fb4bc5f0 35 int TCPServer::listen(int backlog)
nexpaq 0:6c56fb4bc5f0 36 {
nexpaq 0:6c56fb4bc5f0 37 _lock.lock();
nexpaq 0:6c56fb4bc5f0 38 int ret;
nexpaq 0:6c56fb4bc5f0 39
nexpaq 0:6c56fb4bc5f0 40 if (!_socket) {
nexpaq 0:6c56fb4bc5f0 41 ret = NSAPI_ERROR_NO_SOCKET;
nexpaq 0:6c56fb4bc5f0 42 } else {
nexpaq 0:6c56fb4bc5f0 43 ret = _stack->socket_listen(_socket, backlog);
nexpaq 0:6c56fb4bc5f0 44 }
nexpaq 0:6c56fb4bc5f0 45
nexpaq 0:6c56fb4bc5f0 46 _lock.unlock();
nexpaq 0:6c56fb4bc5f0 47 return ret;
nexpaq 0:6c56fb4bc5f0 48 }
nexpaq 0:6c56fb4bc5f0 49
nexpaq 0:6c56fb4bc5f0 50 int TCPServer::accept(TCPSocket *connection, SocketAddress *address)
nexpaq 0:6c56fb4bc5f0 51 {
nexpaq 0:6c56fb4bc5f0 52 _lock.lock();
nexpaq 0:6c56fb4bc5f0 53 int ret;
nexpaq 0:6c56fb4bc5f0 54
nexpaq 0:6c56fb4bc5f0 55 while (true) {
nexpaq 0:6c56fb4bc5f0 56 if (!_socket) {
nexpaq 0:6c56fb4bc5f0 57 ret = NSAPI_ERROR_NO_SOCKET;
nexpaq 0:6c56fb4bc5f0 58 break;
nexpaq 0:6c56fb4bc5f0 59 }
nexpaq 0:6c56fb4bc5f0 60
nexpaq 0:6c56fb4bc5f0 61 _pending = 0;
nexpaq 0:6c56fb4bc5f0 62 void *socket;
nexpaq 0:6c56fb4bc5f0 63 ret = _stack->socket_accept(_socket, &socket, address);
nexpaq 0:6c56fb4bc5f0 64
nexpaq 0:6c56fb4bc5f0 65 if (0 == ret) {
nexpaq 0:6c56fb4bc5f0 66 connection->_lock.lock();
nexpaq 0:6c56fb4bc5f0 67
nexpaq 0:6c56fb4bc5f0 68 if (connection->_socket) {
nexpaq 0:6c56fb4bc5f0 69 connection->close();
nexpaq 0:6c56fb4bc5f0 70 }
nexpaq 0:6c56fb4bc5f0 71
nexpaq 0:6c56fb4bc5f0 72 connection->_stack = _stack;
nexpaq 0:6c56fb4bc5f0 73 connection->_socket = socket;
nexpaq 0:6c56fb4bc5f0 74 connection->_event = Callback<void()>(connection, &TCPSocket::event);
nexpaq 0:6c56fb4bc5f0 75 _stack->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
nexpaq 0:6c56fb4bc5f0 76
nexpaq 0:6c56fb4bc5f0 77 connection->_lock.unlock();
nexpaq 0:6c56fb4bc5f0 78 break;
nexpaq 0:6c56fb4bc5f0 79 } else if (NSAPI_ERROR_WOULD_BLOCK != ret) {
nexpaq 0:6c56fb4bc5f0 80 break;
nexpaq 0:6c56fb4bc5f0 81 } else {
nexpaq 0:6c56fb4bc5f0 82 int32_t count;
nexpaq 0:6c56fb4bc5f0 83
nexpaq 0:6c56fb4bc5f0 84 // Release lock before blocking so other threads
nexpaq 0:6c56fb4bc5f0 85 // accessing this object aren't blocked
nexpaq 0:6c56fb4bc5f0 86 _lock.unlock();
nexpaq 0:6c56fb4bc5f0 87 count = _accept_sem.wait(_timeout);
nexpaq 0:6c56fb4bc5f0 88 _lock.lock();
nexpaq 0:6c56fb4bc5f0 89
nexpaq 0:6c56fb4bc5f0 90 if (count < 1) {
nexpaq 0:6c56fb4bc5f0 91 // Semaphore wait timed out so break out and return
nexpaq 0:6c56fb4bc5f0 92 ret = NSAPI_ERROR_WOULD_BLOCK;
nexpaq 0:6c56fb4bc5f0 93 break;
nexpaq 0:6c56fb4bc5f0 94 }
nexpaq 0:6c56fb4bc5f0 95 }
nexpaq 0:6c56fb4bc5f0 96 }
nexpaq 0:6c56fb4bc5f0 97
nexpaq 0:6c56fb4bc5f0 98 _lock.unlock();
nexpaq 0:6c56fb4bc5f0 99 return ret;
nexpaq 0:6c56fb4bc5f0 100 }
nexpaq 0:6c56fb4bc5f0 101
nexpaq 0:6c56fb4bc5f0 102 void TCPServer::event()
nexpaq 0:6c56fb4bc5f0 103 {
nexpaq 0:6c56fb4bc5f0 104 int32_t acount = _accept_sem.wait(0);
nexpaq 0:6c56fb4bc5f0 105 if (acount <= 1) {
nexpaq 0:6c56fb4bc5f0 106 _accept_sem.release();
nexpaq 0:6c56fb4bc5f0 107 }
nexpaq 0:6c56fb4bc5f0 108
nexpaq 0:6c56fb4bc5f0 109 _pending += 1;
nexpaq 0:6c56fb4bc5f0 110 if (_callback && _pending == 1) {
nexpaq 0:6c56fb4bc5f0 111 _callback();
nexpaq 0:6c56fb4bc5f0 112 }
nexpaq 0:6c56fb4bc5f0 113 }