Includes library modifications to allow access to AIN_4 (AIN_0 / 5)

Committer:
bryantaylor
Date:
Tue Sep 20 21:26:12 2016 +0000
Revision:
0:eafc3fd41f75
hackathon

Who changed what in which revision?

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