Entrega 3er corte - sistemas embebidos

Committer:
Bethory
Date:
Wed May 30 04:46:28 2018 +0000
Revision:
1:fcdb45ee95b9
Parent:
0:6ad07c9019fd
Entrega Final

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bethory 0:6ad07c9019fd 1 /* Socket
Bethory 0:6ad07c9019fd 2 * Copyright (c) 2015 ARM Limited
Bethory 0:6ad07c9019fd 3 *
Bethory 0:6ad07c9019fd 4 * Licensed under the Apache License, Version 2.0 (the "License");
Bethory 0:6ad07c9019fd 5 * you may not use this file except in compliance with the License.
Bethory 0:6ad07c9019fd 6 * You may obtain a copy of the License at
Bethory 0:6ad07c9019fd 7 *
Bethory 0:6ad07c9019fd 8 * http://www.apache.org/licenses/LICENSE-2.0
Bethory 0:6ad07c9019fd 9 *
Bethory 0:6ad07c9019fd 10 * Unless required by applicable law or agreed to in writing, software
Bethory 0:6ad07c9019fd 11 * distributed under the License is distributed on an "AS IS" BASIS,
Bethory 0:6ad07c9019fd 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Bethory 0:6ad07c9019fd 13 * See the License for the specific language governing permissions and
Bethory 0:6ad07c9019fd 14 * limitations under the License.
Bethory 0:6ad07c9019fd 15 */
Bethory 0:6ad07c9019fd 16
Bethory 0:6ad07c9019fd 17 #include "UDPSocket.h"
Bethory 0:6ad07c9019fd 18 #include "Timer.h"
Bethory 0:6ad07c9019fd 19 #include "mbed_assert.h"
Bethory 0:6ad07c9019fd 20
Bethory 0:6ad07c9019fd 21 #define TCP_EVENT "UDP_Events"
Bethory 0:6ad07c9019fd 22 #define READ_FLAG 0x1u
Bethory 0:6ad07c9019fd 23 #define WRITE_FLAG 0x2u
Bethory 0:6ad07c9019fd 24
Bethory 0:6ad07c9019fd 25 UDPSocket::UDPSocket()
Bethory 0:6ad07c9019fd 26 : _pending(0), _event_flag()
Bethory 0:6ad07c9019fd 27 {
Bethory 0:6ad07c9019fd 28 }
Bethory 0:6ad07c9019fd 29
Bethory 0:6ad07c9019fd 30 UDPSocket::~UDPSocket()
Bethory 0:6ad07c9019fd 31 {
Bethory 0:6ad07c9019fd 32 close();
Bethory 0:6ad07c9019fd 33 }
Bethory 0:6ad07c9019fd 34
Bethory 0:6ad07c9019fd 35 nsapi_protocol_t UDPSocket::get_proto()
Bethory 0:6ad07c9019fd 36 {
Bethory 0:6ad07c9019fd 37 return NSAPI_UDP;
Bethory 0:6ad07c9019fd 38 }
Bethory 0:6ad07c9019fd 39
Bethory 0:6ad07c9019fd 40
Bethory 0:6ad07c9019fd 41 nsapi_size_or_error_t UDPSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size)
Bethory 0:6ad07c9019fd 42 {
Bethory 0:6ad07c9019fd 43 SocketAddress address;
Bethory 0:6ad07c9019fd 44 nsapi_size_or_error_t err = _stack->gethostbyname(host, &address);
Bethory 0:6ad07c9019fd 45 if (err) {
Bethory 0:6ad07c9019fd 46 return NSAPI_ERROR_DNS_FAILURE;
Bethory 0:6ad07c9019fd 47 }
Bethory 0:6ad07c9019fd 48
Bethory 0:6ad07c9019fd 49 address.set_port(port);
Bethory 0:6ad07c9019fd 50
Bethory 0:6ad07c9019fd 51 // sendto is thread safe
Bethory 0:6ad07c9019fd 52 return sendto(address, data, size);
Bethory 0:6ad07c9019fd 53 }
Bethory 0:6ad07c9019fd 54
Bethory 0:6ad07c9019fd 55 nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
Bethory 0:6ad07c9019fd 56 {
Bethory 0:6ad07c9019fd 57 _lock.lock();
Bethory 0:6ad07c9019fd 58 nsapi_size_or_error_t ret;
Bethory 0:6ad07c9019fd 59
Bethory 0:6ad07c9019fd 60 while (true) {
Bethory 0:6ad07c9019fd 61 if (!_socket) {
Bethory 0:6ad07c9019fd 62 ret = NSAPI_ERROR_NO_SOCKET;
Bethory 0:6ad07c9019fd 63 break;
Bethory 0:6ad07c9019fd 64 }
Bethory 0:6ad07c9019fd 65
Bethory 0:6ad07c9019fd 66 _pending = 0;
Bethory 0:6ad07c9019fd 67 nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
Bethory 0:6ad07c9019fd 68 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
Bethory 0:6ad07c9019fd 69 ret = sent;
Bethory 0:6ad07c9019fd 70 break;
Bethory 0:6ad07c9019fd 71 } else {
Bethory 0:6ad07c9019fd 72 uint32_t flag;
Bethory 0:6ad07c9019fd 73
Bethory 0:6ad07c9019fd 74 // Release lock before blocking so other threads
Bethory 0:6ad07c9019fd 75 // accessing this object aren't blocked
Bethory 0:6ad07c9019fd 76 _lock.unlock();
Bethory 0:6ad07c9019fd 77 flag = _event_flag.wait_any(WRITE_FLAG, _timeout);
Bethory 0:6ad07c9019fd 78 _lock.lock();
Bethory 0:6ad07c9019fd 79
Bethory 0:6ad07c9019fd 80 if (flag & osFlagsError) {
Bethory 0:6ad07c9019fd 81 // Timeout break
Bethory 0:6ad07c9019fd 82 ret = NSAPI_ERROR_WOULD_BLOCK;
Bethory 0:6ad07c9019fd 83 break;
Bethory 0:6ad07c9019fd 84 }
Bethory 0:6ad07c9019fd 85 }
Bethory 0:6ad07c9019fd 86 }
Bethory 0:6ad07c9019fd 87
Bethory 0:6ad07c9019fd 88 _lock.unlock();
Bethory 0:6ad07c9019fd 89 return ret;
Bethory 0:6ad07c9019fd 90 }
Bethory 0:6ad07c9019fd 91
Bethory 0:6ad07c9019fd 92 nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size)
Bethory 0:6ad07c9019fd 93 {
Bethory 0:6ad07c9019fd 94 _lock.lock();
Bethory 0:6ad07c9019fd 95 nsapi_size_or_error_t ret;
Bethory 0:6ad07c9019fd 96
Bethory 0:6ad07c9019fd 97 while (true) {
Bethory 0:6ad07c9019fd 98 if (!_socket) {
Bethory 0:6ad07c9019fd 99 ret = NSAPI_ERROR_NO_SOCKET;
Bethory 0:6ad07c9019fd 100 break;
Bethory 0:6ad07c9019fd 101 }
Bethory 0:6ad07c9019fd 102
Bethory 0:6ad07c9019fd 103 _pending = 0;
Bethory 0:6ad07c9019fd 104 nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size);
Bethory 0:6ad07c9019fd 105 if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
Bethory 0:6ad07c9019fd 106 ret = recv;
Bethory 0:6ad07c9019fd 107 break;
Bethory 0:6ad07c9019fd 108 } else {
Bethory 0:6ad07c9019fd 109 uint32_t flag;
Bethory 0:6ad07c9019fd 110
Bethory 0:6ad07c9019fd 111 // Release lock before blocking so other threads
Bethory 0:6ad07c9019fd 112 // accessing this object aren't blocked
Bethory 0:6ad07c9019fd 113 _lock.unlock();
Bethory 0:6ad07c9019fd 114 flag = _event_flag.wait_any(READ_FLAG, _timeout);
Bethory 0:6ad07c9019fd 115 _lock.lock();
Bethory 0:6ad07c9019fd 116
Bethory 0:6ad07c9019fd 117 if (flag & osFlagsError) {
Bethory 0:6ad07c9019fd 118 // Timeout break
Bethory 0:6ad07c9019fd 119 ret = NSAPI_ERROR_WOULD_BLOCK;
Bethory 0:6ad07c9019fd 120 break;
Bethory 0:6ad07c9019fd 121 }
Bethory 0:6ad07c9019fd 122 }
Bethory 0:6ad07c9019fd 123 }
Bethory 0:6ad07c9019fd 124
Bethory 0:6ad07c9019fd 125 _lock.unlock();
Bethory 0:6ad07c9019fd 126 return ret;
Bethory 0:6ad07c9019fd 127 }
Bethory 0:6ad07c9019fd 128
Bethory 0:6ad07c9019fd 129 void UDPSocket::event()
Bethory 0:6ad07c9019fd 130 {
Bethory 0:6ad07c9019fd 131 _event_flag.set(READ_FLAG|WRITE_FLAG);
Bethory 0:6ad07c9019fd 132
Bethory 0:6ad07c9019fd 133 _pending += 1;
Bethory 0:6ad07c9019fd 134 if (_callback && _pending == 1) {
Bethory 0:6ad07c9019fd 135 _callback();
Bethory 0:6ad07c9019fd 136 }
Bethory 0:6ad07c9019fd 137 }