Knight KE / Mbed OS Game_Master
Committer:
WFKnight
Date:
Thu Jun 21 13:51:43 2018 +0000
Revision:
0:9b3d4731edbb
UART, RTOS, LED

Who changed what in which revision?

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