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