[IOT-1911] Make resource/csdk/stack W4 compliant.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / arduino / caipclient_eth.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
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
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 ******************************************************************/
20 #include "caipinterface.h"
21
22 #include <Arduino.h>
23 #include <Ethernet.h>
24 #include <socket.h>
25 #include <w5100.h>
26 #include <EthernetUdp.h>
27 #include <IPAddress.h>
28
29 #include "logger.h"
30 #include "cacommon.h"
31 #include "caadapterinterface.h"
32 #include "caipadapter.h"
33 #include "caipnwmonitor.h"
34 #include "caipadapterutils_eth.h"
35 #include "caadapterutils.h"
36 #include "oic_malloc.h"
37 #include "oic_string.h"
38
39 #define TAG "IPC"
40
41 static int g_sockID = 0;
42
43 /**
44  * @var g_unicastPort
45  * @brief Unicast Port
46  */
47 static uint16_t g_unicastPort = 0;
48
49 #define IPv4_MULTICAST     "224.0.1.187"
50
51 void CAIPSetUnicastSocket(int socketID)
52 {
53     OIC_LOG(DEBUG, TAG, "IN");
54     if (0 < socketID)
55     {
56         g_sockID = socketID;
57     }
58     else
59     {
60         OIC_LOG(ERROR, TAG, "sock err");
61     }
62
63     OIC_LOG(DEBUG, TAG, "OUT");
64     return;
65 }
66
67 void CAIPSetUnicastPort(uint16_t port)
68 {
69     OIC_LOG(DEBUG, TAG, "IN");
70     g_unicastPort = port;
71     OIC_LOG(DEBUG, TAG, "OUT");
72     return;
73 }
74
75 void CAIPSendData(CAEndpoint_t *endpoint, const void *buf,
76                   size_t bufLen, bool isMulticast)
77 {
78     if (!isMulticast && 0 == g_unicastPort)
79     {
80         OIC_LOG(ERROR, TAG, "port 0");
81         return;
82     }
83
84     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
85
86     int socketID = 0;
87     uint16_t port = endpoint->port;
88     if (isMulticast)
89     {
90         port = CA_COAP;
91         OICStrcpy(endpoint->addr, sizeof(endpoint->addr), IPv4_MULTICAST);
92         if (CAArduinoInitMulticastUdpSocket(endpoint->addr, port,
93                                             g_unicastPort, &socketID) != CA_STATUS_OK)
94         {
95             OIC_LOG(ERROR, TAG, "init mcast err");
96             return;
97         }
98         OIC_LOG_V(DEBUG, TAG, "MPORT:%u", port);
99         OIC_LOG_V(DEBUG, TAG, "LPORT:%u", g_unicastPort);
100         OIC_LOG_V(DEBUG, TAG, "SOCKET ID:%d", socketID);
101     }
102     else
103     {
104         if (0 == g_sockID)
105         {
106             if (CAArduinoInitUdpSocket(&port, &socketID) != CA_STATUS_OK)
107             {
108                 OIC_LOG(ERROR, TAG, "init ucast err");
109                 return;
110             }
111         }
112         else
113         {
114             socketID = g_sockID;
115         }
116     }
117
118     uint32_t ret;
119     uint8_t ipAddr[4] = { 0 };
120     uint16_t parsedPort = 0;
121     if (CAParseIPv4AddressInternal(endpoint->addr, ipAddr, sizeof(ipAddr),
122                                    &parsedPort) != CA_STATUS_OK)
123     {
124         OIC_LOG(ERROR, TAG, "parse fail");
125         return;
126     }
127
128     if (bufLen > UINT16_MAX)
129     {
130         // This will never happen as max buffer size we are dealing with is COAP_MAX_PDU_SIZE
131         OIC_LOG(ERROR, TAG, "Size exceeded");
132         return;
133     }
134
135     ret = sendto(socketID, (const uint8_t *)buf, (uint16_t)bufLen, ipAddr, port);
136     if (ret <= 0)
137     {
138         OIC_LOG_V(ERROR, TAG, "SendData failed: %d", ret);
139     }
140     if (g_sockID != socketID)
141     {
142         close(socketID);
143     }
144
145     OIC_LOG(DEBUG, TAG, "OUT");
146 }
147