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 "TCPSocket.h"
bryantaylor 0:eafc3fd41f75 18 #include "Timer.h"
bryantaylor 0:eafc3fd41f75 19 #include "mbed_assert.h"
bryantaylor 0:eafc3fd41f75 20
bryantaylor 0:eafc3fd41f75 21 TCPSocket::TCPSocket()
bryantaylor 0:eafc3fd41f75 22 : _pending(0), _read_sem(0), _write_sem(0),
bryantaylor 0:eafc3fd41f75 23 _read_in_progress(false), _write_in_progress(false)
bryantaylor 0:eafc3fd41f75 24 {
bryantaylor 0:eafc3fd41f75 25 }
bryantaylor 0:eafc3fd41f75 26
bryantaylor 0:eafc3fd41f75 27 TCPSocket::~TCPSocket()
bryantaylor 0:eafc3fd41f75 28 {
bryantaylor 0:eafc3fd41f75 29 close();
bryantaylor 0:eafc3fd41f75 30 }
bryantaylor 0:eafc3fd41f75 31
bryantaylor 0:eafc3fd41f75 32 nsapi_protocol_t TCPSocket::get_proto()
bryantaylor 0:eafc3fd41f75 33 {
bryantaylor 0:eafc3fd41f75 34 return NSAPI_TCP;
bryantaylor 0:eafc3fd41f75 35 }
bryantaylor 0:eafc3fd41f75 36
bryantaylor 0:eafc3fd41f75 37 int TCPSocket::connect(const SocketAddress &address)
bryantaylor 0:eafc3fd41f75 38 {
bryantaylor 0:eafc3fd41f75 39 _lock.lock();
bryantaylor 0:eafc3fd41f75 40 int ret;
bryantaylor 0:eafc3fd41f75 41
bryantaylor 0:eafc3fd41f75 42 if (!_socket) {
bryantaylor 0:eafc3fd41f75 43 ret = NSAPI_ERROR_NO_SOCKET;
bryantaylor 0:eafc3fd41f75 44 } else {
bryantaylor 0:eafc3fd41f75 45 ret = _stack->socket_connect(_socket, address);
bryantaylor 0:eafc3fd41f75 46 }
bryantaylor 0:eafc3fd41f75 47
bryantaylor 0:eafc3fd41f75 48 _lock.unlock();
bryantaylor 0:eafc3fd41f75 49 return ret;
bryantaylor 0:eafc3fd41f75 50 }
bryantaylor 0:eafc3fd41f75 51
bryantaylor 0:eafc3fd41f75 52 int TCPSocket::connect(const char *host, uint16_t port)
bryantaylor 0:eafc3fd41f75 53 {
bryantaylor 0:eafc3fd41f75 54 SocketAddress address(_stack, host, port);
bryantaylor 0:eafc3fd41f75 55 if (!address) {
bryantaylor 0:eafc3fd41f75 56 return NSAPI_ERROR_DNS_FAILURE;
bryantaylor 0:eafc3fd41f75 57 }
bryantaylor 0:eafc3fd41f75 58
bryantaylor 0:eafc3fd41f75 59 // connect is thread safe
bryantaylor 0:eafc3fd41f75 60 return connect(address);
bryantaylor 0:eafc3fd41f75 61 }
bryantaylor 0:eafc3fd41f75 62
bryantaylor 0:eafc3fd41f75 63 int TCPSocket::send(const void *data, unsigned size)
bryantaylor 0:eafc3fd41f75 64 {
bryantaylor 0:eafc3fd41f75 65 _lock.lock();
bryantaylor 0:eafc3fd41f75 66 int ret;
bryantaylor 0:eafc3fd41f75 67
bryantaylor 0:eafc3fd41f75 68 // If this assert is hit then there are two threads
bryantaylor 0:eafc3fd41f75 69 // performing a send at the same time which is undefined
bryantaylor 0:eafc3fd41f75 70 // behavior
bryantaylor 0:eafc3fd41f75 71 MBED_ASSERT(!_write_in_progress);
bryantaylor 0:eafc3fd41f75 72 _write_in_progress = true;
bryantaylor 0:eafc3fd41f75 73
bryantaylor 0:eafc3fd41f75 74 while (true) {
bryantaylor 0:eafc3fd41f75 75 if (!_socket) {
bryantaylor 0:eafc3fd41f75 76 ret = NSAPI_ERROR_NO_SOCKET;
bryantaylor 0:eafc3fd41f75 77 break;
bryantaylor 0:eafc3fd41f75 78 }
bryantaylor 0:eafc3fd41f75 79
bryantaylor 0:eafc3fd41f75 80 _pending = 0;
bryantaylor 0:eafc3fd41f75 81 int sent = _stack->socket_send(_socket, data, size);
bryantaylor 0:eafc3fd41f75 82 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
bryantaylor 0:eafc3fd41f75 83 ret = sent;
bryantaylor 0:eafc3fd41f75 84 break;
bryantaylor 0:eafc3fd41f75 85 } else {
bryantaylor 0:eafc3fd41f75 86 int32_t count;
bryantaylor 0:eafc3fd41f75 87
bryantaylor 0:eafc3fd41f75 88 // Release lock before blocking so other threads
bryantaylor 0:eafc3fd41f75 89 // accessing this object aren't blocked
bryantaylor 0:eafc3fd41f75 90 _lock.unlock();
bryantaylor 0:eafc3fd41f75 91 count = _write_sem.wait(_timeout);
bryantaylor 0:eafc3fd41f75 92 _lock.lock();
bryantaylor 0:eafc3fd41f75 93
bryantaylor 0:eafc3fd41f75 94 if (count < 1) {
bryantaylor 0:eafc3fd41f75 95 // Semaphore wait timed out so break out and return
bryantaylor 0:eafc3fd41f75 96 ret = NSAPI_ERROR_WOULD_BLOCK;
bryantaylor 0:eafc3fd41f75 97 break;
bryantaylor 0:eafc3fd41f75 98 }
bryantaylor 0:eafc3fd41f75 99 }
bryantaylor 0:eafc3fd41f75 100 }
bryantaylor 0:eafc3fd41f75 101
bryantaylor 0:eafc3fd41f75 102 _write_in_progress = false;
bryantaylor 0:eafc3fd41f75 103 _lock.unlock();
bryantaylor 0:eafc3fd41f75 104 return ret;
bryantaylor 0:eafc3fd41f75 105 }
bryantaylor 0:eafc3fd41f75 106
bryantaylor 0:eafc3fd41f75 107 int TCPSocket::recv(void *data, unsigned size)
bryantaylor 0:eafc3fd41f75 108 {
bryantaylor 0:eafc3fd41f75 109 _lock.lock();
bryantaylor 0:eafc3fd41f75 110 int ret;
bryantaylor 0:eafc3fd41f75 111
bryantaylor 0:eafc3fd41f75 112 // If this assert is hit then there are two threads
bryantaylor 0:eafc3fd41f75 113 // performing a recv at the same time which is undefined
bryantaylor 0:eafc3fd41f75 114 // behavior
bryantaylor 0:eafc3fd41f75 115 MBED_ASSERT(!_read_in_progress);
bryantaylor 0:eafc3fd41f75 116 _read_in_progress = true;
bryantaylor 0:eafc3fd41f75 117
bryantaylor 0:eafc3fd41f75 118 while (true) {
bryantaylor 0:eafc3fd41f75 119 if (!_socket) {
bryantaylor 0:eafc3fd41f75 120 ret = NSAPI_ERROR_NO_SOCKET;
bryantaylor 0:eafc3fd41f75 121 break;
bryantaylor 0:eafc3fd41f75 122 }
bryantaylor 0:eafc3fd41f75 123
bryantaylor 0:eafc3fd41f75 124 _pending = 0;
bryantaylor 0:eafc3fd41f75 125 int recv = _stack->socket_recv(_socket, data, size);
bryantaylor 0:eafc3fd41f75 126 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
bryantaylor 0:eafc3fd41f75 127 ret = recv;
bryantaylor 0:eafc3fd41f75 128 break;
bryantaylor 0:eafc3fd41f75 129 } else {
bryantaylor 0:eafc3fd41f75 130 int32_t count;
bryantaylor 0:eafc3fd41f75 131
bryantaylor 0:eafc3fd41f75 132 // Release lock before blocking so other threads
bryantaylor 0:eafc3fd41f75 133 // accessing this object aren't blocked
bryantaylor 0:eafc3fd41f75 134 _lock.unlock();
bryantaylor 0:eafc3fd41f75 135 count = _read_sem.wait(_timeout);
bryantaylor 0:eafc3fd41f75 136 _lock.lock();
bryantaylor 0:eafc3fd41f75 137
bryantaylor 0:eafc3fd41f75 138 if (count < 1) {
bryantaylor 0:eafc3fd41f75 139 // Semaphore wait timed out so break out and return
bryantaylor 0:eafc3fd41f75 140 ret = NSAPI_ERROR_WOULD_BLOCK;
bryantaylor 0:eafc3fd41f75 141 break;
bryantaylor 0:eafc3fd41f75 142 }
bryantaylor 0:eafc3fd41f75 143 }
bryantaylor 0:eafc3fd41f75 144 }
bryantaylor 0:eafc3fd41f75 145
bryantaylor 0:eafc3fd41f75 146 _read_in_progress = false;
bryantaylor 0:eafc3fd41f75 147 _lock.unlock();
bryantaylor 0:eafc3fd41f75 148 return ret;
bryantaylor 0:eafc3fd41f75 149 }
bryantaylor 0:eafc3fd41f75 150
bryantaylor 0:eafc3fd41f75 151 void TCPSocket::event()
bryantaylor 0:eafc3fd41f75 152 {
bryantaylor 0:eafc3fd41f75 153 int32_t wcount = _write_sem.wait(0);
bryantaylor 0:eafc3fd41f75 154 if (wcount <= 1) {
bryantaylor 0:eafc3fd41f75 155 _write_sem.release();
bryantaylor 0:eafc3fd41f75 156 }
bryantaylor 0:eafc3fd41f75 157 int32_t rcount = _read_sem.wait(0);
bryantaylor 0:eafc3fd41f75 158 if (rcount <= 1) {
bryantaylor 0:eafc3fd41f75 159 _read_sem.release();
bryantaylor 0:eafc3fd41f75 160 }
bryantaylor 0:eafc3fd41f75 161
bryantaylor 0:eafc3fd41f75 162 _pending += 1;
bryantaylor 0:eafc3fd41f75 163 if (_callback && _pending == 1) {
bryantaylor 0:eafc3fd41f75 164 _callback();
bryantaylor 0:eafc3fd41f75 165 }
bryantaylor 0:eafc3fd41f75 166 }