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