Implement find_usb_serial_port for MacOS, switch HYTE CNVS implementation to serial-based
This commit is contained in:
parent
75bf674537
commit
f03e4fd049
9 changed files with 164 additions and 248 deletions
|
|
@ -10,6 +10,35 @@
|
|||
|
||||
#include "find_usb_serial_port.h"
|
||||
|
||||
std::string exec(const char* cmd)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
FILE* pipe = popen(cmd, "r");
|
||||
|
||||
if(!pipe)
|
||||
{
|
||||
throw std::runtime_error("popen() failed!");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while(fgets(buffer, sizeof(buffer), pipe) != NULL)
|
||||
{
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
pclose(pipe);
|
||||
throw;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| |
|
||||
| find_usb_serial_port |
|
||||
|
|
@ -24,12 +53,121 @@
|
|||
| |
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
std::vector<std::string *> find_usb_serial_port(unsigned short /*vid*/, unsigned short /*pid*/)
|
||||
std::vector<std::string *> find_usb_serial_port(unsigned short vid, unsigned short pid)
|
||||
{
|
||||
std::vector<std::string *> ret_vector;
|
||||
/*-----------------------------------------------------*\
|
||||
| Strings to search for in ioreg output |
|
||||
\*-----------------------------------------------------*/
|
||||
#define IO_CALLOUT_STR "\"IOCalloutDevice\" ="
|
||||
#define ID_VENDOR_STR "\"idVendor\" = "
|
||||
#define ID_PRODUCT_STR "\"idProduct\" = "
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| TODO: Implement for MacOS |
|
||||
\*-----------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Return variables |
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<std::string *> ret_vector;
|
||||
std::string * tmp_string;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Execute command to list USB devices |
|
||||
| |
|
||||
| Top level entry lines in ioreg output start with |
|
||||
| "+-o". Start the string with an extra newline so |
|
||||
| that we can search for "\n+-0" to identify only hits |
|
||||
| at the beginning of a line. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string out_string = "\n" + exec("ioreg -r -c IOUSBHostDevice -l");
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Append desired VID and PID to search strings |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string vid_string = ID_VENDOR_STR + std::to_string(vid);
|
||||
std::string pid_string = ID_PRODUCT_STR + std::to_string(pid);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Start position counter at 0 |
|
||||
\*-----------------------------------------------------*/
|
||||
std::size_t pos = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Loop through ioreg output, loop exits when "\n+-o" |
|
||||
| string cannot be found. |
|
||||
\*-----------------------------------------------------*/
|
||||
while(1)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Variables to store positions in string |
|
||||
\*-------------------------------------------------*/
|
||||
std::size_t next_pos;
|
||||
std::size_t vid_pos;
|
||||
std::size_t pid_pos;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Search for the next 2 iterations of "\n+-o" so |
|
||||
| that we can check if hits are in between them |
|
||||
\*-------------------------------------------------*/
|
||||
pos = out_string.find("\n+-o", pos);
|
||||
next_pos = out_string.find("\n+-o", pos + 1);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Search for the vendor and product ID strings in |
|
||||
| and verify that they are between pos and next_pos |
|
||||
\*-------------------------------------------------*/
|
||||
vid_pos = out_string.find(vid_string, pos);
|
||||
pid_pos = out_string.find(pid_string, pos);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Verify that VID/PID matches are within this |
|
||||
| device block by checking that their positions are |
|
||||
| less than next_pos. If next_pos is invalid, |
|
||||
| this is the last block, in which case check if |
|
||||
| VID/PID positions are valid. |
|
||||
\*-------------------------------------------------*/
|
||||
if(((vid_pos < next_pos) && (pid_pos < next_pos)) || ((pos == std::string::npos) && (vid_pos != std::string::npos) && (pid_pos != std::string::npos)))
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Variables to store positions in string |
|
||||
\*---------------------------------------------*/
|
||||
std::size_t dev_pos;
|
||||
std::size_t start_pos;
|
||||
std::size_t end_pos;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Look for the IO callout device tag and then |
|
||||
| get the start and end positions of its value |
|
||||
\*---------------------------------------------*/
|
||||
dev_pos = out_string.find(IO_CALLOUT_STR, pos + 1);
|
||||
start_pos = out_string.find("\"", dev_pos + sizeof(IO_CALLOUT_STR)) + 1;
|
||||
end_pos = out_string.find("\"\n", start_pos);
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Ensure the IO callout device tag is within |
|
||||
| this device's section |
|
||||
\*---------------------------------------------*/
|
||||
if(dev_pos < next_pos)
|
||||
{
|
||||
tmp_string = new std::string(out_string.substr(start_pos, end_pos-start_pos));
|
||||
ret_vector.push_back(tmp_string);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If we've reached the end of the string, break out |
|
||||
| of the loop |
|
||||
\*-------------------------------------------------*/
|
||||
if(pos == std::string::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Increment position |
|
||||
\*-------------------------------------------------*/
|
||||
pos++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Return vector of detected strings |
|
||||
\*-----------------------------------------------------*/
|
||||
return(ret_vector);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -460,6 +460,8 @@ bool serial_port::serial_open()
|
|||
| Configure baud rate |
|
||||
\*-----------------------------------------*/
|
||||
ioctl(file_descriptor, IOSSIOSPEED, &baud_rate);
|
||||
|
||||
printf("Port opened fd %d", file_descriptor);
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
|
@ -595,9 +597,10 @@ int serial_port::serial_write(char * buffer, int length)
|
|||
\*-----------------------------------------------------*/
|
||||
#ifdef __APPLE__
|
||||
int byteswritten;
|
||||
tcdrain(file_descriptor);
|
||||
byteswritten = write(file_descriptor, buffer, length);
|
||||
tcdrain(file_descriptor);
|
||||
printf("serial write fd %d", file_descriptor);
|
||||
printf("tcdrain %d\r\n",tcdrain(file_descriptor));
|
||||
printf("write %d\r\n", byteswritten = write(file_descriptor, buffer, length));
|
||||
printf("tcdrain %d\r\n", tcdrain(file_descriptor));
|
||||
return byteswritten;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue