1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "caipinterface_singlethread.h"
27 #include <utility/server_drv.h>
28 #include <utility/wifi_drv.h>
29 #include <IPAddress.h>
33 #include "cainterface.h"
34 #include "caadapterinterface.h"
35 #include "caipadapter_singlethread.h"
36 #include "caadapterutils.h"
37 #include "oic_malloc.h"
41 // Length of the IP address decimal notation string
42 #define IPNAMESIZE (16)
44 // Start offsets based on end of received data buffer
45 #define IP_RECBUF_IPADDR_OFFSET (6)
46 #define IP_RECBUF_PORT_OFFSET (2)
48 #define IP_RECBUF_IPADDR_SIZE (IP_RECBUF_IPADDR_OFFSET - IP_RECBUF_PORT_OFFSET)
49 #define IP_RECBUF_PORT_SIZE (IP_RECBUF_PORT_OFFSET - 0)
50 #define IP_RECBUF_FOOTER_SIZE (IP_RECBUF_IPADDR_SIZE + IP_RECBUF_PORT_SIZE)
52 static CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
53 static void CAArduinoCheckData();
54 static void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
55 const void *data, const uint32_t dataLength);
57 static CAIPPacketReceivedCallback gPacketReceivedCallback = NULL;
58 static int32_t gUnicastSocket = 0;
59 static bool gServerRunning = false;
62 CAResult_t CAIPInitializeServer(void)
65 * This API is to keep design in sync with other platforms.
66 * The required implementation is done in Start() api's.
71 void CAIPTerminateServer(void)
74 * This API is to keep design in sync with other platforms.
75 * The required implementation is done in Stop() api's.
79 CAResult_t CAIPGetUnicastServerInfo(char **ipAddress, uint16_t *port, int *serverID)
82 * This API is to keep design in sync with other platforms.
83 * Will be implemented as and when CA layer wants this info.
88 CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
89 bool forceStart, int *serverFD)
91 OIC_LOG(DEBUG, TAG, "IN");
92 VERIFY_NON_NULL(port, TAG, "port");
97 OIC_LOG(DEBUG, TAG, "Error");
98 return CA_STATUS_FAILED;
101 if (WiFi.status() != WL_CONNECTED)
103 OIC_LOG(ERROR, TAG, "ERROR:No WIFI");
104 return CA_STATUS_FAILED;
107 char localIpAddress[CA_IPADDR_SIZE];
108 int32_t localIpAddressLen = sizeof(localIpAddress);
109 CAArduinoGetInterfaceAddress(localIpAddress, localIpAddressLen);
110 OIC_LOG_V(DEBUG, TAG, "address: %s", localIpAddress);
111 OIC_LOG_V(DEBUG, TAG, "port: %d", *port);
113 Udp.begin((uint16_t ) *port);
114 gServerRunning = true;
116 OIC_LOG(DEBUG, TAG, "OUT");
120 CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
121 uint16_t multicastPort, int *serverFD)
123 // wifi shield does not support multicast
124 OIC_LOG(DEBUG, TAG, "IN");
125 OIC_LOG(DEBUG, TAG, "OUT");
126 return CA_NOT_SUPPORTED;
129 CAResult_t CAIPStopUnicastServer()
131 OIC_LOG(DEBUG, TAG, "IN");
134 gServerRunning = false;
135 OIC_LOG(DEBUG, TAG, "OUT");
139 CAResult_t CAIPStopMulticastServer()
141 return CAIPStopUnicastServer();
144 void CAPacketReceivedCallback(const char *ipAddress, const uint16_t port,
145 const void *data, const uint32_t dataLength)
147 OIC_LOG(DEBUG, TAG, "IN");
148 if (gPacketReceivedCallback)
150 gPacketReceivedCallback(ipAddress, port, data, dataLength);
151 OIC_LOG(DEBUG, TAG, "Notified network packet");
153 OIC_LOG(DEBUG, TAG, "OUT");
156 void CAArduinoCheckData()
158 OIC_LOG(DEBUG, TAG, "IN");
159 char addr[IPNAMESIZE] = {0};
160 uint16_t senderPort = 0;
161 int16_t packetSize = Udp.parsePacket();
162 OIC_LOG_V(DEBUG, TAG, "Rcv packet of size:%d ", packetSize);
165 packetSize = packetSize > COAP_MAX_PDU_SIZE ? COAP_MAX_PDU_SIZE:packetSize;
166 char *data = (char *)OICMalloc(packetSize + 1);
171 IPAddress remoteIp = Udp.remoteIP();
172 senderPort = Udp.remotePort();
173 sprintf(addr, "%d.%d.%d.%d", remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3]);
174 OIC_LOG_V(DEBUG, TAG, "remoteip: %s, port: %d", addr, senderPort);
175 // read the packet into packetBufffer
176 int32_t dataLen = Udp.read(data, COAP_MAX_PDU_SIZE);
181 CAPacketReceivedCallback(addr, senderPort, data, dataLen);
184 OIC_LOG(DEBUG, TAG, "OUT");
187 void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
189 OIC_LOG(DEBUG, TAG, "IN");
190 gPacketReceivedCallback = callback;
191 OIC_LOG(DEBUG, TAG, "OUT");
194 void CAIPSetExceptionCallback(CAIPExceptionCallback callback)
201 CAArduinoCheckData();
204 /// Retrieves the IP address assigned to Arduino WiFi shield
205 CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
207 OIC_LOG(DEBUG, TAG, "IN");
208 if (WiFi.status() != WL_CONNECTED)
210 OIC_LOG(DEBUG, TAG, "No WIFI");
211 return CA_STATUS_FAILED;
214 VERIFY_NON_NULL(address, TAG, "Invalid address");
215 if (addrLen < IPNAMESIZE)
217 OIC_LOG_V(ERROR, TAG, "AddrLen MUST be atleast %d", IPNAMESIZE);
218 return CA_STATUS_FAILED;
221 IPAddress ip = WiFi.localIP();
222 sprintf((char *)address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
224 OIC_LOG_V(DEBUG, TAG, "Wifi shield address is: %s", address);
225 OIC_LOG(DEBUG, TAG, "OUT");