Updater.cc
Go to the documentation of this file.
1 
37 #include "Updater.hh"
38 #include "Messages.hh"
39 #include "crc.h"
40 
41 #include <iostream>
42 #include <fstream>
43 #include <string>
44 
45 int Updater::Receive(uint8_t * buf, const size_t len, long int *RxLen)
46 {
47 
48  int ret = 0;
49  struct sockaddr_in PeerAddr;
50  long int BytesReceived = 0;
51 #if WIN32
52  int PeerLength = sizeof(struct sockaddr_in);
53 #else
54  socklen_t PeerLength = sizeof(struct sockaddr_in);
55 #endif
56 
57  // Disable narrowing conversion warning for 'len' argument
58 #if defined(WIN32) && !defined(__MINGW64__)
59 #pragma warning (push)
60 #pragma warning (disable : 4267)
61 #endif
62  BytesReceived = recvfrom(m_Ip->Sock(), (char*)buf, len, 0, (struct sockaddr *)&PeerAddr, &PeerLength);
63 #if defined(WIN32) && !defined(__MINGW64__)
64 #pragma warning (pop)
65 #endif
66  if (BytesReceived<0) {
67  if (SOCKET_ERRNO != CRL_EAGAIN)
68  std::cerr << "Failed to receive from socket: " << SOCKET_STR_ERR <<std::endl;
69  return -SOCKET_ERRNO;
70  } else if (BytesReceived==0) {
71  std::cerr << "Socket connection closed!\n";
72  return -1;
73  }
74 
75  if (RxLen)
76  *RxLen = BytesReceived;
77 
78  ret = BytesReceived;
79  return ret;
80 }
81 
82  int Updater::Send(uint8_t * buf, const size_t len)
83  {
84 
85 #if WIN32
86  int PeerLength = sizeof(struct sockaddr_in);
87 #else
88  socklen_t PeerLength = sizeof(struct sockaddr_in);
89 #endif
90  long int Sent = 0;
91  struct sockaddr_in server = m_Ip->Server();
92 
93  // Disable narrowing conversion warning for 'len' argument
94 #if defined(WIN32) && !defined(__MINGW64__)
95 #pragma warning (push)
96 #pragma warning (disable : 4267)
97 #endif
98  Sent = sendto(m_Ip->Sock(), (char*)buf, len, 0, (struct sockaddr *)&server, PeerLength);
99 #if defined(WIN32) && !defined(__MINGW64__)
100 #pragma warning (pop)
101 #endif
102  if (Sent<0)
103  {
104  std::cerr << "Failed to send to socket: " << SOCKET_STR_ERR << std::endl;
105  }
106  else if (Sent == 0)
107  {
108  std::cerr << "Sent 0 len datagram on socket!\n";
109  }
110 
111  return Sent;
112 
113 }
114 
115 int Updater::SendFile(std::string &filePath, bool verbose)
116 {
117  int ret = 0;
118  uint32_t crc32_final = 0;
119  uint32_t crc32_initial = 0;
120  uint32_t bytesWritten = 0;
121  int32_t blockSeq=0;
122  long int bytesRcvd = 0;
123  uint8_t chunk[Messages::BLOCK_SIZE] = {};
124 
125  std::ifstream file;
126  try {
127  file.open(filePath, std::ios::in | std::ios::binary);
128  if (!file.good()) {
129  std::cerr << "Cannot open file: `" << filePath << "`\n";
130  return -1;
131  }
132 
133  } catch (const std::exception &e) {
134  std::cerr << "Exception accessing `" << filePath << "` Error: " << e.what() << std::endl;
135  return -1;
136  }
137 
138  file.seekg(0, file.end);
139  long long fileLength = file.tellg();
140  file.seekg(0, file.beg);
141 
142  long long l;
143  do {
144 
145  file.read((char *)chunk, Messages::BLOCK_SIZE);
146  l = file.gcount();
147  crc32_initial = crc32(crc32_initial, chunk, static_cast<uint32_t>(l));
148 
149  } while(!file.eof());
150 
151  crc32_final = crc32_initial;
152 
153  file.clear();
154  file.seekg(0, file.beg);
155 
156  const long long numBlocks = fileLength/Messages::BLOCK_SIZE;
157  if (fileLength > MAX_UPDATE_FS) {
158  std::cerr << "Update file too large (" << fileLength << "B), can't send\n";
159  return -1;
160  }
161  Messages::MessageBlockAck BlockAck;
162 
163  do {
164  uint32_t sent = 0;
165 
166  file.read((char *)chunk, Messages::BLOCK_SIZE);
167  l = file.gcount();
168 
169  if (l == 0)
170  {
171  std::cerr << "Error: Failed to read chunk from File\n";
172  file.close();
173  return -1;
174  }
175 
176  Messages::MessageFileBlock Block(static_cast<uint32_t>(fileLength), bytesWritten, crc32_final, static_cast<uint32_t>(l), blockSeq++, chunk);
177  sent = Send((uint8_t*)&Block, sizeof(Block));
178  if (sent!=sizeof(Block))
179  {
180  std::cerr << "Warning: Truncated send expected: " << sizeof(Block) << " sent: " << sent << std::endl;
181  }
182 
183  bytesWritten += static_cast<uint32_t>(l);
184 
185  bytesRcvd = Receive((uint8_t *)&BlockAck, sizeof(BlockAck), NULL);
186  if (bytesRcvd < 0)
187  {
188  std::cerr << "Socket timed out waiting for ACK, check connections and try again\n";
189  file.close();
190  exit(1);
191  }
192 
193  if (bytesRcvd < (long int)sizeof(BlockAck))
194  {
195  std::cerr << "Invalid ACK\n";
196  }
197 
198  if (BlockAck.Sequence != Block.Sequence)
199  {
200  std::cerr << "Invalid Sequence, Resending block\n";
201  }
202 
203  if (verbose)
204  std::cout << "Sending Block (" << BlockAck.Sequence << "/" << numBlocks << ")\r";
205 
206  } while(!file.eof());
207 
208  std::cout << "Finished sending file to camera!\n";
209  file.close();
210  return ret;
211 }
Updater::SendFile
int SendFile(std::string &FilePath, bool verbose)
Definition: Updater.cc:115
Updater::Receive
int Receive(uint8_t *buf, const size_t len, long int *rxlen)
Definition: Updater.cc:45
crc.h
Updater::Send
int Send(uint8_t *buf, const size_t len)
Definition: Updater.cc:82
Messages::MessageFileBlock
Definition: Messages.hh:172
Updater::m_Ip
Ip * m_Ip
Definition: Updater.hh:62
Messages.hh
SOCKET_STR_ERR
#define SOCKET_STR_ERR
Definition: Legacy/include/MultiSense/details/utility/Portability.hh:101
CRL_EAGAIN
#define CRL_EAGAIN
Definition: Legacy/include/MultiSense/details/utility/Portability.hh:102
Ip::Server
struct sockaddr_in Server()
Definition: Ip.hh:100
MAX_UPDATE_FS
#define MAX_UPDATE_FS
Definition: Updater.hh:43
SOCKET_ERRNO
#define SOCKET_ERRNO
Definition: Legacy/include/MultiSense/details/utility/Portability.hh:100
Messages::MessageBlockAck
Definition: Messages.hh:162
Updater.hh
Ip::Sock
socket_t Sock()
Definition: Ip.hh:95
crc32
uint32_t crc32(uint32_t crc, const void *buf, uint32_t size)
Definition: crc.c:91
Messages::BLOCK_SIZE
static CRL_CONSTEXPR int BLOCK_SIZE
Definition: Messages.hh:62


multisense_lib
Author(s):
autogenerated on Thu Apr 17 2025 02:49:09