iowfehu;gdbjwHJAOPIHO?L

Fork of X_NUCLEO_IDW01M1 by ST

Committer:
mridup
Date:
Mon May 09 10:38:22 2016 +0000
Revision:
6:e7a3fca2df10
Parent:
5:c83ffd44f40a
Child:
7:0fdd186a7d90
Socket Server support.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mridup 0:dc55f40eb04f 1 /* SpwfSAInterface implementation of NetworkInterfaceAPI
mridup 0:dc55f40eb04f 2 * Copyright (c) 2015 ARM Limited
mridup 0:dc55f40eb04f 3 *
mridup 0:dc55f40eb04f 4 * Licensed under the Apache License, Version 2.0 (the "License");
mridup 0:dc55f40eb04f 5 * you may not use this file except in compliance with the License.
mridup 0:dc55f40eb04f 6 * You may obtain a copy of the License at
mridup 0:dc55f40eb04f 7 *
mridup 0:dc55f40eb04f 8 * http://www.apache.org/licenses/LICENSE-2.0
mridup 0:dc55f40eb04f 9 *
mridup 0:dc55f40eb04f 10 * Unless required by applicable law or agreed to in writing, software
mridup 0:dc55f40eb04f 11 * distributed under the License is distributed on an "AS IS" BASIS,
mridup 0:dc55f40eb04f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mridup 0:dc55f40eb04f 13 * See the License for the specific language governing permissions and
mridup 0:dc55f40eb04f 14 * limitations under the License.
mridup 0:dc55f40eb04f 15 */
mridup 0:dc55f40eb04f 16
mridup 0:dc55f40eb04f 17 #include "SPWFInterface.h"
mridup 0:dc55f40eb04f 18
mridup 0:dc55f40eb04f 19 // Various timeouts for different SPWF operations
mridup 0:dc55f40eb04f 20 #define SPWF_CONNECT_TIMEOUT 20000
mridup 0:dc55f40eb04f 21 #define SPWF_SEND_TIMEOUT 500
mridup 5:c83ffd44f40a 22 #define SPWF_RECV_TIMEOUT 2000
mridup 0:dc55f40eb04f 23 #define SPWF_MISC_TIMEOUT 15000
mridup 5:c83ffd44f40a 24
mridup 5:c83ffd44f40a 25 // Handle structure for socket
mridup 5:c83ffd44f40a 26 struct spwf_socket {
mridup 5:c83ffd44f40a 27 int id;
mridup 6:e7a3fca2df10 28 int server_port;
mridup 5:c83ffd44f40a 29 nsapi_protocol_t proto;
mridup 5:c83ffd44f40a 30 bool connected;
mridup 5:c83ffd44f40a 31 };
mridup 0:dc55f40eb04f 32
mridup 0:dc55f40eb04f 33 // SpwfSAInterface implementation
mridup 0:dc55f40eb04f 34 SpwfSAInterface::SpwfSAInterface(PinName tx, PinName rx, PinName rst, PinName wkup, PinName rts, bool debug)
mridup 0:dc55f40eb04f 35 : _spwf(tx, rx, rst, wkup, rts)
mridup 0:dc55f40eb04f 36 {
mridup 0:dc55f40eb04f 37 memset(_ids, 0, sizeof(_ids));
mridup 3:fd9d20c4d3f0 38 isInitialized = false;
mridup 6:e7a3fca2df10 39 isListening = false;
mridup 0:dc55f40eb04f 40 }
mridup 0:dc55f40eb04f 41
mridup 0:dc55f40eb04f 42 SpwfSAInterface::~SpwfSAInterface()
mridup 0:dc55f40eb04f 43 {
mridup 0:dc55f40eb04f 44 }
mridup 0:dc55f40eb04f 45
mridup 5:c83ffd44f40a 46 int SpwfSAInterface::init(void)
mridup 0:dc55f40eb04f 47 {
mridup 0:dc55f40eb04f 48 _spwf.setTimeout(SPWF_MISC_TIMEOUT);
mridup 0:dc55f40eb04f 49 return (_spwf.init());
mridup 0:dc55f40eb04f 50 }
mridup 0:dc55f40eb04f 51
mridup 5:c83ffd44f40a 52 int SpwfSAInterface::connect(
mridup 0:dc55f40eb04f 53 const char *ap,
mridup 0:dc55f40eb04f 54 const char *pass_phrase,
mridup 5:c83ffd44f40a 55 nsapi_security_t security)
mridup 0:dc55f40eb04f 56 {
mridup 3:fd9d20c4d3f0 57 //initialize the device before connecting
mridup 3:fd9d20c4d3f0 58 if(!isInitialized)
mridup 3:fd9d20c4d3f0 59 {
mridup 3:fd9d20c4d3f0 60 if(init()==0)
mridup 3:fd9d20c4d3f0 61 isInitialized=true;
mridup 5:c83ffd44f40a 62 else return NSAPI_ERROR_DEVICE_ERROR;
mridup 3:fd9d20c4d3f0 63 }
mridup 3:fd9d20c4d3f0 64
mridup 0:dc55f40eb04f 65 _spwf.setTimeout(SPWF_CONNECT_TIMEOUT);
mridup 0:dc55f40eb04f 66
mridup 5:c83ffd44f40a 67 if(security == NSAPI_SECURITY_WPA2) return NSAPI_ERROR_DEVICE_ERROR;
mridup 0:dc55f40eb04f 68
mridup 0:dc55f40eb04f 69 WiFi_Priv_Mode mode = (WiFi_Priv_Mode)security;
mridup 0:dc55f40eb04f 70
mridup 0:dc55f40eb04f 71 return (_spwf.connect((char*)ap, (char*)pass_phrase, mode));//0 on success
mridup 0:dc55f40eb04f 72 }
mridup 0:dc55f40eb04f 73
mridup 5:c83ffd44f40a 74 int SpwfSAInterface::disconnect()
mridup 5:c83ffd44f40a 75 {
mridup 0:dc55f40eb04f 76 return (_spwf.disconnect());
mridup 0:dc55f40eb04f 77 }
mridup 0:dc55f40eb04f 78
mridup 5:c83ffd44f40a 79 const char *SpwfSAInterface::get_ip_address()
mridup 0:dc55f40eb04f 80 {
mridup 0:dc55f40eb04f 81 return _spwf.getIPAddress();
mridup 0:dc55f40eb04f 82 }
mridup 0:dc55f40eb04f 83
mridup 5:c83ffd44f40a 84 const char *SpwfSAInterface::get_mac_address()
mridup 0:dc55f40eb04f 85 {
mridup 0:dc55f40eb04f 86 return _spwf.getMACAddress();
mridup 0:dc55f40eb04f 87 }
mridup 0:dc55f40eb04f 88
mridup 5:c83ffd44f40a 89
mridup 5:c83ffd44f40a 90 int SpwfSAInterface::socket_open(void **handle, nsapi_protocol_t proto)
mridup 0:dc55f40eb04f 91 {
mridup 5:c83ffd44f40a 92 // Look for an unused socket
mridup 5:c83ffd44f40a 93 int id = -1;
mridup 5:c83ffd44f40a 94
mridup 5:c83ffd44f40a 95 struct spwf_socket *socket = new struct spwf_socket;
mridup 5:c83ffd44f40a 96 if (!socket) {
mridup 5:c83ffd44f40a 97 return NSAPI_ERROR_NO_SOCKET;
mridup 5:c83ffd44f40a 98 }
mridup 5:c83ffd44f40a 99
mridup 5:c83ffd44f40a 100 socket->id = id;
mridup 6:e7a3fca2df10 101 socket->server_port = id;
mridup 5:c83ffd44f40a 102 socket->proto = proto;
mridup 5:c83ffd44f40a 103 socket->connected = false;
mridup 5:c83ffd44f40a 104 *handle = socket;
mridup 5:c83ffd44f40a 105 return 0;
mridup 0:dc55f40eb04f 106 }
mridup 5:c83ffd44f40a 107
mridup 5:c83ffd44f40a 108 int SpwfSAInterface::socket_connect(void *handle, const SocketAddress &addr)
mridup 5:c83ffd44f40a 109 {
mridup 6:e7a3fca2df10 110 uint8_t sock_id = 99;
mridup 5:c83ffd44f40a 111 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 5:c83ffd44f40a 112
mridup 5:c83ffd44f40a 113 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t";//"s" for secure socket?
mridup 0:dc55f40eb04f 114
mridup 5:c83ffd44f40a 115 _spwf.socket_client_open((uint8_t*)addr.get_ip_address(), (uint32_t)addr.get_port(), (uint8_t *)proto, &sock_id);//sock ID is allocated NOW
mridup 0:dc55f40eb04f 116
mridup 0:dc55f40eb04f 117 //TODO: Maintain a socket table to map socket ID to host & port
mridup 0:dc55f40eb04f 118 //TODO: lookup on client table to see if already socket is allocated to same host/port
mridup 0:dc55f40eb04f 119 //multimap <char *, vector <uint16_t> > ::iterator i = c_table.find((char*)ip);
mridup 0:dc55f40eb04f 120
mridup 0:dc55f40eb04f 121 if(sock_id <= SPWFSA_SOCKET_COUNT)
mridup 0:dc55f40eb04f 122 {
mridup 5:c83ffd44f40a 123 //_ids[socket->id] = false;
mridup 5:c83ffd44f40a 124 socket->id = sock_id;//the socket ID of this Socket instance
mridup 5:c83ffd44f40a 125 _ids[socket->id] = true;
mridup 5:c83ffd44f40a 126 socket->connected = true;
mridup 0:dc55f40eb04f 127 }
mridup 0:dc55f40eb04f 128 else
mridup 5:c83ffd44f40a 129 return NSAPI_ERROR_NO_SOCKET;
mridup 0:dc55f40eb04f 130
mridup 0:dc55f40eb04f 131 return 0;//0 means SUCCESS
mridup 0:dc55f40eb04f 132 }
mridup 5:c83ffd44f40a 133
mridup 5:c83ffd44f40a 134 int SpwfSAInterface::socket_bind(void *handle, const SocketAddress &address)
mridup 5:c83ffd44f40a 135 {
mridup 6:e7a3fca2df10 136 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 6:e7a3fca2df10 137 socket->id = SERVER_SOCKET_NO;//Special socket ID number for Server Socket
mridup 6:e7a3fca2df10 138 socket->server_port = address.get_port();
mridup 6:e7a3fca2df10 139 return 0;
mridup 5:c83ffd44f40a 140 }
mridup 5:c83ffd44f40a 141
mridup 5:c83ffd44f40a 142 int SpwfSAInterface::socket_listen(void *handle, int backlog)
mridup 0:dc55f40eb04f 143 {
mridup 6:e7a3fca2df10 144 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 6:e7a3fca2df10 145 int err;
mridup 6:e7a3fca2df10 146
mridup 6:e7a3fca2df10 147 if(socket->server_port==-1 || isListening)
mridup 6:e7a3fca2df10 148 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or already listening
mridup 6:e7a3fca2df10 149
mridup 6:e7a3fca2df10 150 const char *proto = (socket->proto == NSAPI_UDP) ? "u" : "t";
mridup 6:e7a3fca2df10 151
mridup 6:e7a3fca2df10 152 err = _spwf.socket_server_open((uint32_t)socket->server_port, (uint8_t *)proto);
mridup 6:e7a3fca2df10 153
mridup 6:e7a3fca2df10 154 if(err==0)
mridup 6:e7a3fca2df10 155 {
mridup 6:e7a3fca2df10 156 isListening = true;
mridup 6:e7a3fca2df10 157 }
mridup 6:e7a3fca2df10 158 else
mridup 6:e7a3fca2df10 159 return NSAPI_ERROR_DEVICE_ERROR;
mridup 6:e7a3fca2df10 160
mridup 6:e7a3fca2df10 161 return err;
mridup 5:c83ffd44f40a 162 }
mridup 5:c83ffd44f40a 163
mridup 6:e7a3fca2df10 164 /** Accepts a connection on a TCP socket
mridup 6:e7a3fca2df10 165 *
mridup 6:e7a3fca2df10 166 * The server socket must be bound and set to listen for connections.
mridup 6:e7a3fca2df10 167 * On a new connection, creates a network socket using the specified
mridup 6:e7a3fca2df10 168 * socket instance.
mridup 6:e7a3fca2df10 169 *
mridup 6:e7a3fca2df10 170 * By default, accept blocks until data is sent. If socket is set to
mridup 6:e7a3fca2df10 171 * non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned
mridup 6:e7a3fca2df10 172 * immediately.
mridup 6:e7a3fca2df10 173 *
mridup 6:e7a3fca2df10 174 * @param socket TCPSocket instance that will handle the incoming connection.
mridup 6:e7a3fca2df10 175 * @return 0 on success, negative error code on failure
mridup 6:e7a3fca2df10 176 */
mridup 5:c83ffd44f40a 177 int SpwfSAInterface::socket_accept(void **handle, void *server)
mridup 5:c83ffd44f40a 178 {
mridup 6:e7a3fca2df10 179 char debug_str[10];
mridup 6:e7a3fca2df10 180 struct spwf_socket *server_socket = (struct spwf_socket *)server;
mridup 6:e7a3fca2df10 181 int id = -1;
mridup 6:e7a3fca2df10 182
mridup 6:e7a3fca2df10 183 if(server_socket->server_port==-1 || !isListening)
mridup 6:e7a3fca2df10 184 return NSAPI_ERROR_NO_SOCKET; //server socket not bound or not listening
mridup 6:e7a3fca2df10 185
mridup 6:e7a3fca2df10 186 while(true)
mridup 6:e7a3fca2df10 187 {
mridup 6:e7a3fca2df10 188 if(_spwf.get_wait_for_incoming_client())
mridup 6:e7a3fca2df10 189 {
mridup 6:e7a3fca2df10 190 server_socket->connected = true;
mridup 6:e7a3fca2df10 191
mridup 6:e7a3fca2df10 192 //struct spwf_socket *temp_socket;// = new struct spwf_socket;//create new network socket
mridup 6:e7a3fca2df10 193 struct spwf_socket *socket = new struct spwf_socket;//create new network socket
mridup 6:e7a3fca2df10 194 if (!socket) {
mridup 6:e7a3fca2df10 195 return NSAPI_ERROR_NO_SOCKET;
mridup 6:e7a3fca2df10 196 }
mridup 6:e7a3fca2df10 197
mridup 6:e7a3fca2df10 198 memset(socket, 0, sizeof (struct spwf_socket));
mridup 6:e7a3fca2df10 199 /*
mridup 6:e7a3fca2df10 200 if(get_network_socket(&temp_socket)!=0)
mridup 6:e7a3fca2df10 201 {
mridup 6:e7a3fca2df10 202 return NSAPI_ERROR_NO_SOCKET;
mridup 6:e7a3fca2df10 203 }*/
mridup 6:e7a3fca2df10 204
mridup 6:e7a3fca2df10 205 socket->id = server_socket->id;
mridup 6:e7a3fca2df10 206 socket->server_port = server_socket->server_port;
mridup 6:e7a3fca2df10 207 socket->proto = server_socket->proto;
mridup 6:e7a3fca2df10 208 socket->connected = true;
mridup 6:e7a3fca2df10 209
mridup 6:e7a3fca2df10 210 *handle = socket;
mridup 6:e7a3fca2df10 211 socket = 0;
mridup 6:e7a3fca2df10 212 _spwf.set_wait_for_incoming_client(false);//reset
mridup 6:e7a3fca2df10 213 wait_ms(50);//CHECK:TODO:Why do we need this?
mridup 6:e7a3fca2df10 214 break;
mridup 6:e7a3fca2df10 215 }
mridup 6:e7a3fca2df10 216 }
mridup 6:e7a3fca2df10 217
mridup 6:e7a3fca2df10 218 return 0;
mridup 5:c83ffd44f40a 219 }
mridup 5:c83ffd44f40a 220
mridup 6:e7a3fca2df10 221 /*
mridup 6:e7a3fca2df10 222 int SpwfSAInterface::get_network_socket(struct spwf_socket **handle)
mridup 6:e7a3fca2df10 223 {
mridup 6:e7a3fca2df10 224 struct spwf_socket *__socket = new struct spwf_socket;//create new network socket
mridup 6:e7a3fca2df10 225 __socket = new struct spwf_socket;//create new network socket
mridup 6:e7a3fca2df10 226 if (!__socket) {
mridup 6:e7a3fca2df10 227 return NSAPI_ERROR_NO_SOCKET;
mridup 6:e7a3fca2df10 228 }
mridup 6:e7a3fca2df10 229
mridup 6:e7a3fca2df10 230 memset(__socket, 0, sizeof (struct spwf_socket));
mridup 6:e7a3fca2df10 231 *handle = __socket;
mridup 6:e7a3fca2df10 232 return 0;
mridup 6:e7a3fca2df10 233 }
mridup 6:e7a3fca2df10 234 */
mridup 6:e7a3fca2df10 235
mridup 5:c83ffd44f40a 236 int SpwfSAInterface::socket_close(void *handle)
mridup 5:c83ffd44f40a 237 {
mridup 5:c83ffd44f40a 238 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 5:c83ffd44f40a 239 int err = 0;
mridup 5:c83ffd44f40a 240 //_spwf.setTimeout(SPWF_MISC_TIMEOUT);
mridup 0:dc55f40eb04f 241
mridup 5:c83ffd44f40a 242 if(socket->id!=-1)
mridup 5:c83ffd44f40a 243 {
mridup 6:e7a3fca2df10 244 if(socket->id==SERVER_SOCKET_NO)
mridup 6:e7a3fca2df10 245 {
mridup 6:e7a3fca2df10 246 if (_spwf.socket_server_close()==-1) {
mridup 6:e7a3fca2df10 247 err = NSAPI_ERROR_DEVICE_ERROR;
mridup 6:e7a3fca2df10 248 }
mridup 6:e7a3fca2df10 249 isListening = false;
mridup 5:c83ffd44f40a 250 }
mridup 6:e7a3fca2df10 251 else
mridup 6:e7a3fca2df10 252 {
mridup 6:e7a3fca2df10 253 if (_spwf.socket_client_close(socket->id)==-1) {
mridup 6:e7a3fca2df10 254 err = NSAPI_ERROR_DEVICE_ERROR;
mridup 6:e7a3fca2df10 255 }
mridup 6:e7a3fca2df10 256 _ids[socket->id] = false;
mridup 6:e7a3fca2df10 257 }
mridup 5:c83ffd44f40a 258 }
mridup 5:c83ffd44f40a 259
mridup 5:c83ffd44f40a 260 delete socket;
mridup 0:dc55f40eb04f 261 return err;
mridup 0:dc55f40eb04f 262 }
mridup 5:c83ffd44f40a 263
mridup 5:c83ffd44f40a 264 int SpwfSAInterface::socket_send(void *handle, const void *data, unsigned size)
mridup 5:c83ffd44f40a 265 {
mridup 5:c83ffd44f40a 266 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 5:c83ffd44f40a 267 int err;
mridup 0:dc55f40eb04f 268
mridup 6:e7a3fca2df10 269 if(socket->id==SERVER_SOCKET_NO)
mridup 6:e7a3fca2df10 270 {
mridup 6:e7a3fca2df10 271 err = _spwf.socket_server_write((uint16_t)size, (char*)data);
mridup 6:e7a3fca2df10 272 }
mridup 6:e7a3fca2df10 273 else
mridup 6:e7a3fca2df10 274 {
mridup 6:e7a3fca2df10 275 err = _spwf.socket_client_write((uint8_t)socket->id, (uint16_t)size, (char*)data);
mridup 6:e7a3fca2df10 276 }
mridup 0:dc55f40eb04f 277
mridup 0:dc55f40eb04f 278 return err;
mridup 0:dc55f40eb04f 279 }
mridup 0:dc55f40eb04f 280
mridup 0:dc55f40eb04f 281 //return no of bytes read
mridup 5:c83ffd44f40a 282 int SpwfSAInterface::socket_recv(void *handle, void *data, unsigned size)
mridup 0:dc55f40eb04f 283 {
mridup 5:c83ffd44f40a 284 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 0:dc55f40eb04f 285 int32_t recv;
mridup 0:dc55f40eb04f 286
mridup 5:c83ffd44f40a 287 _spwf.setTimeout(SPWF_RECV_TIMEOUT);
mridup 0:dc55f40eb04f 288
mridup 6:e7a3fca2df10 289 //CHECK:Receive for both Client and Server Sockets same?
mridup 5:c83ffd44f40a 290 recv = _spwf.socket_client_recv((uint8_t)socket->id, (uint16_t)size, (char*)data);
mridup 5:c83ffd44f40a 291 if (recv < 0) {
mridup 5:c83ffd44f40a 292 return NSAPI_ERROR_WOULD_BLOCK;
mridup 5:c83ffd44f40a 293 }
mridup 0:dc55f40eb04f 294 return recv;
mridup 0:dc55f40eb04f 295
mridup 0:dc55f40eb04f 296 }
mridup 0:dc55f40eb04f 297
mridup 5:c83ffd44f40a 298 int SpwfSAInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
mridup 5:c83ffd44f40a 299 {
mridup 5:c83ffd44f40a 300 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 5:c83ffd44f40a 301 if (!socket->connected) {
mridup 5:c83ffd44f40a 302 int err = socket_connect(socket, addr);
mridup 5:c83ffd44f40a 303 if (err < 0) {
mridup 5:c83ffd44f40a 304 return err;
mridup 5:c83ffd44f40a 305 }
mridup 5:c83ffd44f40a 306 }
mridup 5:c83ffd44f40a 307
mridup 5:c83ffd44f40a 308 return socket_send(socket, data, size);
mridup 5:c83ffd44f40a 309 }
mridup 5:c83ffd44f40a 310
mridup 5:c83ffd44f40a 311 int SpwfSAInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
mridup 5:c83ffd44f40a 312 {
mridup 5:c83ffd44f40a 313 struct spwf_socket *socket = (struct spwf_socket *)handle;
mridup 5:c83ffd44f40a 314 return socket_recv(socket, data, size);
mridup 5:c83ffd44f40a 315 }
mridup 5:c83ffd44f40a 316
mridup 5:c83ffd44f40a 317 void SpwfSAInterface::socket_attach(void *handle, void (*callback)(void *), void *data)
mridup 5:c83ffd44f40a 318 {
mridup 5:c83ffd44f40a 319 //No implementation yet
mridup 5:c83ffd44f40a 320 }
mridup 5:c83ffd44f40a 321
mridup 0:dc55f40eb04f 322 void SpwfSAInterface::debug(const char * string)
mridup 0:dc55f40eb04f 323 {
mridup 0:dc55f40eb04f 324 _spwf.debug_print(string);
mridup 0:dc55f40eb04f 325 }