1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This API only works with:
30 #include "twsocketlist.h"
32 #include "oic_malloc.h"
41 #define TAG "TWSocketList"
46 * Apply terminal settings.
49 static int SetTerminalInfo(int fd, int speed, int parity, int shouldBlock);
53 * Internal function to close socket. For outside callers to close a socket, they must properly
54 * call TWDeleteTWSock() for the same affect to ensure all things are cleaned up on shutdown.
57 TWResultCode TWCloseTWSock(TWSock * sock);
59 static TWSock * g_twSockList = NULL;
61 TWResultCode TWAddTWSock(TWSock * sock, PIPlugin_Zigbee * plugin, const char * fileLoc)
63 if(!sock || !plugin || !fileLoc)
65 return TW_RESULT_ERROR_INVALID_PARAMS;
70 LL_FOREACH_SAFE(g_twSockList, out, temp)
74 // Ignore requests to add a socket that's already in the queue.
79 sock->plugin = plugin;
80 sock->fd = open(fileLoc, O_RDWR | O_NOCTTY | O_SYNC);
83 OIC_LOG_V(INFO, TAG, "Could not open port. Errno is: %d\n", errno);
84 return TW_RESULT_ERROR;
87 // set speed to 19,200 bps, 8n1 (no parity), no blocking.
88 int ret = SetTerminalInfo(sock->fd, DEVICE_BAUDRATE, 0, 0);
91 TWResultCode result = TWCloseTWSock(sock);
92 if(result != TW_RESULT_OK)
96 return TW_RESULT_ERROR;
101 pthread_mutexattr_t mutexAttr;
102 pthread_mutexattr_init(&mutexAttr);
103 pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
104 pthread_mutex_init(&(sock->mutex), &mutexAttr); // TODO: Use OIC_MUTEX instead.
105 pthread_cond_init(&(sock->queueCV), NULL);
107 sock->isActive = true;
109 LL_APPEND(g_twSockList, sock);
113 TWSock * TWGetSock(PIPlugin_Zigbee * plugin)
121 LL_FOREACH_SAFE(g_twSockList, out, tmp)
123 if(out->plugin == plugin)
131 TWResultCode TWCloseTWSock(TWSock * sock)
135 return TW_RESULT_ERROR_INVALID_PARAMS;
137 int ret = close(sock->fd);
140 OIC_LOG_V(ERROR, TAG, "Could not close port. Errno is: %d", errno);
141 return TW_RESULT_ERROR;
146 TWResultCode TWDeleteTWSock(TWSock * sock)
150 return TW_RESULT_ERROR_INVALID_PARAMS;
154 LL_FOREACH_SAFE(g_twSockList, out, tmp)
158 LL_DELETE(g_twSockList, out);
162 OICFree(sock->buffer);
164 TWFreeQueue(sock->plugin);
166 int mutexRet = pthread_mutex_destroy(&(sock->mutex));
169 OIC_LOG_V(ERROR, TAG, "Failed to destroy mutex. Error: %d", mutexRet);
170 return TW_RESULT_ERROR;
172 TWResultCode result = TWCloseTWSock(sock);
177 TWResultCode TWDeleteAllTWSock()
181 LL_FOREACH_SAFE(g_twSockList, out, tmp)
190 * Apply interface attribute values to terminal settings.
193 int SetTerminalInfo(int fd, int speed, int parity, int shouldBlock)
195 OIC_LOG(INFO, TAG, "Enter SetTerminalInfo()");
198 struct termios terminalInfo = {
203 ret = tcgetattr(fd, &terminalInfo);
206 OIC_LOG_V(ERROR, TAG, "tcgetattr() - ret=%d errno=%d", ret, errno);
212 ret = cfsetispeed (&terminalInfo, speed);
215 OIC_LOG_V(ERROR, TAG, "cfsetispeed() - ret=%d errno=%d", ret, errno);
221 ret = cfsetospeed (&terminalInfo, speed);
224 OIC_LOG_V(ERROR, TAG, "cfsetospeed() - ret=%d errno=%d", ret, errno);
229 terminalInfo.c_cflag = (terminalInfo.c_cflag & ~CSIZE); //byte size
230 terminalInfo.c_cflag |= CS8; //byte size is 8
232 terminalInfo.c_cflag &= ~PARENB; //no parity
233 terminalInfo.c_cflag |= parity; //no parity
235 terminalInfo.c_cflag &= ~CSTOPB; //1 stop bit
237 terminalInfo.c_cflag |= CREAD; //enable the receiver
239 //Input Control Settings
240 terminalInfo.c_iflag &= ~IGNBRK; //break condition
242 //Local Mode Settings
243 terminalInfo.c_lflag = 0;
245 // whether to block on read and read time-out
246 terminalInfo.c_cc[VMIN] = (shouldBlock >= 1) ? 1 : 0;
247 terminalInfo.c_cc[VTIME] = 5;
249 //Input Control Settings
250 terminalInfo.c_oflag = 0;
253 ret = tcsetattr (fd, TCSANOW, &terminalInfo);
256 OIC_LOG_V(ERROR, TAG, "tcsetattr - ret=%d errno=%d", ret, errno);
261 OIC_LOG_V(INFO, TAG, "Leave SetTerminalInfo() with ret=%d", ret);