1 /*
2  * Author: Jon Trulson <jtrulson@ics.com>
3  * Copyright (c) 2014 Intel Corporation.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <iostream>
26 #include <string>
27 #include <stdexcept>
28 
29 #include "ublox6.h"
30 
31 using namespace upm;
32 using namespace std;
33 
Ublox6(int uart)34 Ublox6::Ublox6(int uart)
35 {
36   m_ttyFd = -1;
37 
38   if ( !(m_uart = mraa_uart_init(uart)) )
39     {
40       throw std::invalid_argument(std::string(__FUNCTION__) +
41                                   ": mraa_uart_init() failed");
42       return;
43     }
44 
45   // This requires a recent MRAA (1/2015)
46   const char *devPath = mraa_uart_get_dev_path(m_uart);
47 
48   if (!devPath)
49     {
50       throw std::runtime_error(std::string(__FUNCTION__) +
51                                ": mraa_uart_get_dev_path() failed");
52       return;
53     }
54 
55   // now open the tty
56   if ( (m_ttyFd = open(devPath, O_RDWR)) == -1)
57     {
58       string err = __FUNCTION__;
59       err += ": open of " + std::string(devPath) + " failed: " +
60         std::string(strerror(errno));
61 
62       throw std::runtime_error(err);
63       return;
64     }
65 }
66 
~Ublox6()67 Ublox6::~Ublox6()
68 {
69   if (m_ttyFd != -1)
70     close(m_ttyFd);
71 }
72 
dataAvailable()73 bool Ublox6::dataAvailable()
74 {
75   if (m_ttyFd == -1)
76     return false;
77 
78   struct timeval timeout;
79 
80   // no waiting
81   timeout.tv_sec = 0;
82   timeout.tv_usec = 0;
83 
84   int nfds;
85   fd_set readfds;
86 
87   FD_ZERO(&readfds);
88 
89   FD_SET(m_ttyFd, &readfds);
90 
91   if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0)
92     return true;                // data is ready
93   else
94     return false;
95 }
96 
readData(char * buffer,int len)97 int Ublox6::readData(char *buffer, int len)
98 {
99   if (m_ttyFd == -1)
100     return(-1);
101 
102   int rv = read(m_ttyFd, buffer, len);
103 
104   if (rv < 0)
105     {
106       string err = string(__FUNCTION__) + ": read failed: " +
107         string(strerror(errno));
108 
109       throw std::runtime_error(err);
110       return rv;
111     }
112 
113   return rv;
114 }
115 
writeData(char * buffer,int len)116 int Ublox6::writeData(char * buffer, int len)
117 {
118   if (m_ttyFd == -1)
119     return(-1);
120 
121   int rv = write(m_ttyFd, buffer, len);
122 
123   if (rv < 0)
124     {
125       string err = string(__FUNCTION__) + ": write failed: " +
126         string(strerror(errno));
127 
128       throw std::runtime_error(err);
129       return rv;
130     }
131 
132   tcdrain(m_ttyFd);
133 
134   return rv;
135 }
136 
setupTty(speed_t baud)137 bool Ublox6::setupTty(speed_t baud)
138 {
139   if (m_ttyFd == -1)
140     return(false);
141 
142   struct termios termio;
143 
144   // get current modes
145   tcgetattr(m_ttyFd, &termio);
146 
147   // setup for a 'raw' mode.  81N, no echo or special character
148   // handling, such as flow control.
149   cfmakeraw(&termio);
150 
151   // set our baud rates
152   cfsetispeed(&termio, baud);
153   cfsetospeed(&termio, baud);
154 
155   // make it so
156   int rv;
157   if ( (rv = tcsetattr(m_ttyFd, TCSAFLUSH, &termio)) < 0)
158     {
159       string err = string(__FUNCTION__) + ": tcsetattr failed: " +
160         string(strerror(errno));
161 
162       throw std::runtime_error(err);
163       return false;
164     }
165 
166   return true;
167 }
168