Jack Hansdampf / mbed-mqtt-GSOE1

Dependents:   ESP8266MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQTTLinux.c Source File

MQTTLinux.c

00001 /*******************************************************************************
00002  * Copyright (c) 2014, 2017 IBM Corp.
00003  *
00004  * All rights reserved. This program and the accompanying materials
00005  * are made available under the terms of the Eclipse Public License v1.0
00006  * and Eclipse Distribution License v1.0 which accompany this distribution.
00007  *
00008  * The Eclipse Public License is available at
00009  *    http://www.eclipse.org/legal/epl-v10.html
00010  * and the Eclipse Distribution License is available at
00011  *   http://www.eclipse.org/org/documents/edl-v10.php.
00012  *
00013  * Contributors:
00014  *    Allan Stockdill-Mander - initial API and implementation and/or initial documentation
00015  *    Ian Craggs - return codes from linux_read
00016  *******************************************************************************/
00017 
00018 #include "MQTTLinux.h"
00019 
00020 void TimerInit(Timer* timer)
00021 {
00022     timer->end_time = (struct timeval){0, 0};
00023 }
00024 
00025 char TimerIsExpired(Timer* timer)
00026 {
00027     struct timeval now, res;
00028     gettimeofday(&now, NULL);
00029     timersub(&timer->end_time, &now, &res);
00030     return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0);
00031 }
00032 
00033 
00034 void TimerCountdownMS(Timer* timer, unsigned int timeout)
00035 {
00036     struct timeval now;
00037     gettimeofday(&now, NULL);
00038     struct timeval interval = {timeout / 1000, (timeout % 1000) * 1000};
00039     timeradd(&now, &interval, &timer->end_time);
00040 }
00041 
00042 
00043 void TimerCountdown(Timer* timer, unsigned int timeout)
00044 {
00045     struct timeval now;
00046     gettimeofday(&now, NULL);
00047     struct timeval interval = {timeout, 0};
00048     timeradd(&now, &interval, &timer->end_time);
00049 }
00050 
00051 
00052 int TimerLeftMS(Timer* timer)
00053 {
00054     struct timeval now, res;
00055     gettimeofday(&now, NULL);
00056     timersub(&timer->end_time, &now, &res);
00057     //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000);
00058     return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000;
00059 }
00060 
00061 
00062 int linux_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
00063 {
00064     struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
00065     if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))
00066     {
00067         interval.tv_sec = 0;
00068         interval.tv_usec = 100;
00069     }
00070 
00071     setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));
00072 
00073     int bytes = 0;
00074     while (bytes < len)
00075     {
00076         int rc = recv(n->my_socket, &buffer[bytes], (size_t)(len - bytes), 0);
00077         if (rc == -1)
00078         {
00079             if (errno != EAGAIN && errno != EWOULDBLOCK)
00080               bytes = -1;
00081             break;
00082         }
00083         else if (rc == 0)
00084         {
00085             bytes = 0;
00086             break;
00087         }
00088         else
00089             bytes += rc;
00090     }
00091     return bytes;
00092 }
00093 
00094 
00095 int linux_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
00096 {
00097     struct timeval tv;
00098 
00099     tv.tv_sec = 0;  /* 30 Secs Timeout */
00100     tv.tv_usec = timeout_ms * 1000;  // Not init'ing this can cause strange errors
00101 
00102     setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv,sizeof(struct timeval));
00103     int rc = write(n->my_socket, buffer, len);
00104     return rc;
00105 }
00106 
00107 
00108 void NetworkInit(Network* n)
00109 {
00110     n->my_socket = 0;
00111     n->mqttread = linux_read;
00112     n->mqttwrite = linux_write;
00113 }
00114 
00115 
00116 int NetworkConnect(Network* n, char* addr, int port)
00117 {
00118     int type = SOCK_STREAM;
00119     struct sockaddr_in address;
00120     int rc = -1;
00121     sa_family_t family = AF_INET;
00122     struct addrinfo *result = NULL;
00123     struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};
00124 
00125     if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0)
00126     {
00127         struct addrinfo* res = result;
00128 
00129         /* prefer ip4 addresses */
00130         while (res)
00131         {
00132             if (res->ai_family == AF_INET)
00133             {
00134                 result = res;
00135                 break;
00136             }
00137             res = res->ai_next;
00138         }
00139 
00140         if (result->ai_family == AF_INET)
00141         {
00142             address.sin_port = htons(port);
00143             address.sin_family = family = AF_INET;
00144             address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
00145         }
00146         else
00147             rc = -1;
00148 
00149         freeaddrinfo(result);
00150     }
00151 
00152     if (rc == 0)
00153     {
00154         n->my_socket = socket(family, type, 0);
00155         if (n->my_socket != -1)
00156             rc = connect(n->my_socket, (struct sockaddr*)&address, sizeof(address));
00157         else
00158             rc = -1;
00159     }
00160 
00161     return rc;
00162 }
00163 
00164 
00165 void NetworkDisconnect(Network* n)
00166 {
00167     close(n->my_socket);
00168 }