• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2014, 2015 IBM Corp.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * and Eclipse Distribution License v1.0 which accompany this distribution.
7  *
8  * The Eclipse Public License is available at
9  *    http://www.eclipse.org/legal/epl-v10.html
10  * and the Eclipse Distribution License is available at
11  *   http://www.eclipse.org/org/documents/edl-v10.php.
12  *
13  * Contributors:
14  *    Allan Stockdill-Mander - initial API and implementation and/or initial documentation
15  *    Ian Craggs - convert to FreeRTOS
16  *******************************************************************************/
17 
18 #include "MQTTFreeRTOS.h"
19 
20 
ThreadStart(Thread * thread,void (* fn)(void *),void * arg)21 int ThreadStart(Thread* thread, void (*fn)(void*), void* arg)
22 {
23 	int rc = 0;
24 	uint16_t usTaskStackSize = (configMINIMAL_STACK_SIZE * 5);
25 	UBaseType_t uxTaskPriority = uxTaskPriorityGet(NULL); /* set the priority as the same as the calling task*/
26 
27 	rc = xTaskCreate(fn,	/* The function that implements the task. */
28 		"MQTTTask",			/* Just a text name for the task to aid debugging. */
29 		usTaskStackSize,	/* The stack size is defined in FreeRTOSIPConfig.h. */
30 		arg,				/* The task parameter, not used in this case. */
31 		uxTaskPriority,		/* The priority assigned to the task is defined in FreeRTOSConfig.h. */
32 		&thread->task);		/* The task handle is not used. */
33 
34 	return rc;
35 }
36 
37 
MutexInit(Mutex * mutex)38 void MutexInit(Mutex* mutex)
39 {
40 	mutex->sem = xSemaphoreCreateMutex();
41 }
42 
MutexLock(Mutex * mutex)43 int MutexLock(Mutex* mutex)
44 {
45 	return xSemaphoreTake(mutex->sem, portMAX_DELAY);
46 }
47 
MutexUnlock(Mutex * mutex)48 int MutexUnlock(Mutex* mutex)
49 {
50 	return xSemaphoreGive(mutex->sem);
51 }
52 
53 
TimerCountdownMS(Timer * timer,unsigned int timeout_ms)54 void TimerCountdownMS(Timer* timer, unsigned int timeout_ms)
55 {
56 	timer->xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
57 	vTaskSetTimeOutState(&timer->xTimeOut); /* Record the time at which this function was entered. */
58 }
59 
60 
TimerCountdown(Timer * timer,unsigned int timeout)61 void TimerCountdown(Timer* timer, unsigned int timeout)
62 {
63 	TimerCountdownMS(timer, timeout * 1000);
64 }
65 
66 
TimerLeftMS(Timer * timer)67 int TimerLeftMS(Timer* timer)
68 {
69 	xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait); /* updates xTicksToWait to the number left */
70 	return (timer->xTicksToWait < 0) ? 0 : (timer->xTicksToWait * portTICK_PERIOD_MS);
71 }
72 
73 
TimerIsExpired(Timer * timer)74 char TimerIsExpired(Timer* timer)
75 {
76 	return xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait) == pdTRUE;
77 }
78 
79 
TimerInit(Timer * timer)80 void TimerInit(Timer* timer)
81 {
82 	timer->xTicksToWait = 0;
83 	memset(&timer->xTimeOut, '\0', sizeof(timer->xTimeOut));
84 }
85 
86 
FreeRTOS_read(Network * n,unsigned char * buffer,int len,int timeout_ms)87 int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
88 {
89 	TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
90 	TimeOut_t xTimeOut;
91 	int recvLen = 0;
92 
93 	vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
94 	do
95 	{
96 		int rc = 0;
97 
98 		FreeRTOS_setsockopt(n->my_socket, 0, FREERTOS_SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
99 		rc = FreeRTOS_recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
100 		if (rc > 0)
101 			recvLen += rc;
102 		else if (rc < 0)
103 		{
104 			recvLen = rc;
105 			break;
106 		}
107 	} while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
108 
109 	return recvLen;
110 }
111 
112 
FreeRTOS_write(Network * n,unsigned char * buffer,int len,int timeout_ms)113 int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
114 {
115 	TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
116 	TimeOut_t xTimeOut;
117 	int sentLen = 0;
118 
119 	vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
120 	do
121 	{
122 		int rc = 0;
123 
124 		FreeRTOS_setsockopt(n->my_socket, 0, FREERTOS_SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
125 		rc = FreeRTOS_send(n->my_socket, buffer + sentLen, len - sentLen, 0);
126 		if (rc > 0)
127 			sentLen += rc;
128 		else if (rc < 0)
129 		{
130 			sentLen = rc;
131 			break;
132 		}
133 	} while (sentLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
134 
135 	return sentLen;
136 }
137 
138 
FreeRTOS_disconnect(Network * n)139 void FreeRTOS_disconnect(Network* n)
140 {
141 	FreeRTOS_closesocket(n->my_socket);
142 }
143 
144 
NetworkInit(Network * n)145 void NetworkInit(Network* n)
146 {
147 	n->my_socket = 0;
148 	n->mqttread = FreeRTOS_read;
149 	n->mqttwrite = FreeRTOS_write;
150 	n->disconnect = FreeRTOS_disconnect;
151 }
152 
153 
NetworkConnect(Network * n,char * addr,int port)154 int NetworkConnect(Network* n, char* addr, int port)
155 {
156 	struct freertos_sockaddr sAddr;
157 	int retVal = -1;
158 	uint32_t ipAddress;
159 
160 	if ((ipAddress = FreeRTOS_gethostbyname(addr)) == 0)
161 		goto exit;
162 
163 	sAddr.sin_port = FreeRTOS_htons(port);
164 	sAddr.sin_addr = ipAddress;
165 
166 	if ((n->my_socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP)) < 0)
167 		goto exit;
168 
169 	if ((retVal = FreeRTOS_connect(n->my_socket, &sAddr, sizeof(sAddr))) < 0)
170 	{
171 		FreeRTOS_closesocket(n->my_socket);
172 	    goto exit;
173 	}
174 
175 exit:
176 	return retVal;
177 }
178 
179 
180 #if 0
181 int NetworkConnectTLS(Network *n, char* addr, int port, SlSockSecureFiles_t* certificates, unsigned char sec_method, unsigned int cipher, char server_verify)
182 {
183 	SlSockAddrIn_t sAddr;
184 	int addrSize;
185 	int retVal;
186 	unsigned long ipAddress;
187 
188 	retVal = sl_NetAppDnsGetHostByName(addr, strlen(addr), &ipAddress, AF_INET);
189 	if (retVal < 0) {
190 		return -1;
191 	}
192 
193 	sAddr.sin_family = AF_INET;
194 	sAddr.sin_port = sl_Htons((unsigned short)port);
195 	sAddr.sin_addr.s_addr = sl_Htonl(ipAddress);
196 
197 	addrSize = sizeof(SlSockAddrIn_t);
198 
199 	n->my_socket = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);
200 	if (n->my_socket < 0) {
201 		return -1;
202 	}
203 
204 	SlSockSecureMethod method;
205 	method.secureMethod = sec_method;
206 	retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method));
207 	if (retVal < 0) {
208 		return retVal;
209 	}
210 
211 	SlSockSecureMask mask;
212 	mask.secureMask = cipher;
213 	retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &mask, sizeof(mask));
214 	if (retVal < 0) {
215 		return retVal;
216 	}
217 
218 	if (certificates != NULL) {
219 		retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_FILES, certificates->secureFiles, sizeof(SlSockSecureFiles_t));
220 		if (retVal < 0)
221 		{
222 			return retVal;
223 		}
224 	}
225 
226 	retVal = sl_Connect(n->my_socket, (SlSockAddr_t *)&sAddr, addrSize);
227 	if (retVal < 0) {
228 		if (server_verify || retVal != -453) {
229 			sl_Close(n->my_socket);
230 			return retVal;
231 		}
232 	}
233 
234 	SysTickIntRegister(SysTickIntHandler);
235 	SysTickPeriodSet(80000);
236 	SysTickEnable();
237 
238 	return retVal;
239 }
240 #endif
241