Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / caipclient.c
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 <sys/types.h>
23 #include <sys/socket.h>
24 #include <arpa/inet.h>
25 #include <netinet/in.h>
26 #include <errno.h>
27
28 #include "caadapterutils.h"
29
30 /**
31  * @def IP_CLIENT_TAG
32  * @brief Logging tag for module name
33  */
34 #define IP_CLIENT_TAG "IP_CLIENT"
35 #define OC_MULTICAST_IP "224.0.1.187"
36
37 static uint32_t CASendData(const char *remoteAddress, uint16_t port, const void *data,
38                            uint32_t dataLength, int sockfd)
39 {
40     OIC_LOG(DEBUG, IP_CLIENT_TAG, "IN");
41
42     VERIFY_NON_NULL_RET(remoteAddress, IP_CLIENT_TAG, "IP address is NULL", 0);
43     VERIFY_NON_NULL_RET(data, IP_CLIENT_TAG, "data is NULL", 0);
44
45     if (0 == dataLength)
46     {
47         OIC_LOG(ERROR, IP_CLIENT_TAG, "Data length is 0!");
48         return 0;
49     }
50
51     if (0 > sockfd)
52     {
53         OIC_LOG(ERROR, IP_CLIENT_TAG, "Unicast Server is not running!");
54         return 0;
55     }
56
57     struct sockaddr_in destAddr = { 0 };
58     destAddr.sin_family = AF_INET;
59     destAddr.sin_port = htons(port);
60
61     int ret = inet_pton(AF_INET, remoteAddress, &(destAddr.sin_addr));
62     if (1 != ret)
63     {
64         OIC_LOG(ERROR, IP_CLIENT_TAG, "inet_pton failed!");
65         return 0;
66     }
67
68     ssize_t sendDataLength = sendto(sockfd, data, dataLength, 0, (struct sockaddr *) &destAddr,
69                                     sizeof(destAddr));
70     if (-1 == sendDataLength)
71     {
72         OIC_LOG_V(ERROR, IP_CLIENT_TAG, "sendto failed, Error code: %s",
73                   strerror(errno));
74         return 0;
75     }
76
77     OIC_LOG_V(INFO, IP_CLIENT_TAG, "Sending data is successful, sent bytes[%d] to ip[%s:%d]",
78               sendDataLength, remoteAddress, port);
79     OIC_LOG(DEBUG, IP_CLIENT_TAG, "OUT");
80     return sendDataLength;
81 }
82
83 uint32_t CAIPSendData(const char *remoteAddress, uint16_t remotePort, const void *data,
84                             uint32_t dataLength, bool isMulticast, bool isSecured)
85 {
86     u_arraylist_t *tempServerInfoList = u_arraylist_create();
87     if (!tempServerInfoList)
88     {
89         OIC_LOG(ERROR, IP_CLIENT_TAG, "u_arraylist_create failed");
90         return 0;
91     }
92
93     CAResult_t res = CAGetIPServerInfoList(&tempServerInfoList);
94     if (CA_STATUS_OK != res)
95     {
96         OIC_LOG(ERROR, IP_CLIENT_TAG, "CAGetIPServerInfoList failed");
97         CAClearServerInfoList(tempServerInfoList);
98         return 0;
99     }
100
101     uint32_t len = 0;
102     if (isMulticast || strcmp(remoteAddress, OC_MULTICAST_IP) == 0)
103     {
104         uint32_t listIndex = 0;
105         uint32_t listLength = u_arraylist_length(tempServerInfoList);
106         for (listIndex = 0; listIndex < listLength; listIndex++)
107         {
108             CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
109                                                                       listIndex);
110             if (!info || info->isMulticastServer || info->isSecured)
111             {
112                 continue;
113             }
114
115             if (info->socketFd < 0)
116             {
117                 OIC_LOG(ERROR, IP_CLIENT_TAG, "Invalid Socket Fd");
118                 continue;
119             }
120
121             OIC_LOG_V(DEBUG, IP_CLIENT_TAG,
122                       "CA IP Multicast SendData with src ip %s port %d sockFd %d",
123                       info->ipAddress, info->port, info->socketFd);
124             len = CASendData(remoteAddress, remotePort, data, dataLength, info->socketFd);
125         }
126     }
127     else
128     {
129         int sockFd = CAGetSocketFdForUnicastServer(tempServerInfoList, remoteAddress, isSecured,
130                                                    isMulticast, CA_IPV4);
131
132         if (sockFd < 0)
133         {
134             OIC_LOG(ERROR, IP_CLIENT_TAG, "Invalid Socket Fd");
135             CAClearServerInfoList(tempServerInfoList);
136             return len;
137         }
138
139         OIC_LOG_V(DEBUG, IP_CLIENT_TAG, "IP unicast SendData sockFd %d", sockFd);
140
141         len = CASendData(remoteAddress, remotePort, data, dataLength, sockFd);
142
143     }
144     CAClearServerInfoList(tempServerInfoList);
145     return len;
146 }
147