Open a device by name using libftdi or libusb - c++

I am using libftdi with multiple ftdi devices for a program running on Ubuntu 14.04. I have a udev rule that detects the devices based on a custom manufacturer string and gives them a symlink in the dev directory. It would look similar to /dev/my-device. I would like to use libftdi to open the device using this string instead of the pid/vid/serial number.
I did not see that this capability was available in libftdi so I checked libusb and didn't see that functionality either.

You could try this:
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen) {
char buffer[256];
int rval, i;
// make standard request GET_DESCRIPTOR, type string and given index
// (e.g. dev->iProduct)
rval = usb_control_msg(dev,
USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
buffer, sizeof(buffer), 1000);
if (rval < 0) // error
return rval;
// rval should be bytes read, but buffer[0] contains the actual response size
if ((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0]; // string is shorter than bytes read
if (buffer[1] != USB_DT_STRING) // second byte is the data type
return 0; // invalid return type
// we're dealing with UTF-16LE here so actual chars is half of rval,
// and index 0 doesn't count
rval /= 2;
/* lossy conversion to ISO Latin1 */
for (i = 1; i < rval && i < buflen; i++) {
if (buffer[2 * i + 1] == 0)
buf[i - 1] = buffer[2 * i];
else
buf[i - 1] = '?'; /* outside of ISO Latin1 range */
}
buf[i - 1] = 0;
return i - 1;
}
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName) {
struct usb_bus *bus;
struct usb_device *dev;
char devVendor[256], devProduct[256];
usb_dev_handle * handle = NULL;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor != vendor ||
dev->descriptor.idProduct != product)
continue;
/* we need to open the device in order to query strings */
if (!(handle = usb_open(dev))) {
fprintf(stderr, "Warning: cannot open USB device: %sn",
usb_strerror());
continue;
}
/* get vendor name */
if (usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query manufacturer for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
/* get product name */
if (usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query product for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
if (strcmp(devVendor, vendorName) == 0 &&
strcmp(devProduct, productName) == 0)
return handle;
else
usb_close(handle);
}
}
return NULL;
}

Related

How to use bitwise manipulation to decode machine language into mips assembly? Using c++ to code add, nand, lw, sw, beq, halt

I have written the code that reads the file with machine language, saved the values into an array for memory. I am iterating through the array and for each index, I am using that number to manipulate the bits to do what the binary representation is telling it to do. The only problem is I am not sure how to do this?
I tried storing in separate variables and adding later. I want to do this by shifting the bits to the left and right but then I am not sure how I would store the bits/value. Im not sure how to get this done tbh.
int main (int argc, char *argv[]) {
char line[MAXLINELENGTH];
stateType state;
for (int i = 0; i < NUMREGS; i++)
{
state.reg[i] = 0;
}
FILE *filePtr;
if (argc != 2) {
printf("error: usage: %s <machine-code file>\n", argv[0]);
exit(1);
}
filePtr = fopen(argv[1], "r");
if (filePtr == NULL) {
printf("error: can't open file %s", argv[1]);
perror("fopen");
exit(1);
}
/* read in the entire machine-code file into memory */
for (state.numMemory = 0; fgets(line, MAXLINELENGTH, filePtr) != NULL;
state.numMemory++) {
if (sscanf(line, "%d", state.mem+state.numMemory) != 1) {
printf("error in reading address %d\n", state.numMemory);
exit(1);
}
printf("memory[%d]=%d\n", state.numMemory, state.mem[state.numMemory]);
}
printState(&state);
for (int i = 0; i < state.numMemory + 1; i++ ) {
int opcode = (state.mem[i] >> 22);
if (opcode == 0) {
int regA = (state.mem[i] >> 19) - opcode;
int regB = (state.mem[i] >> 16) - opcode;
int destReg = regA + regB;
}
else if (opcode == 1) {
int regA = (state.mem[i] >> 19) - opcode;
int regB = (state.mem[i] >> 16) - opcode;
int destReg = !(regA && regB);
}

FLASH_If_Write and HardFault

I am using stm32f4 and I am trying to write some data on dual bank flash.
I am calling the below function in my code after the clean flash.
uint32_t totalBlockNumber;
uint32_t blockNumber;
uint8_t blockData[512];
uint32_t frameDataCount;
(frameDataCount always > 8)
Flash_Write_Start(totalBlockNumber,blockNumber,(frameDataCount - 8), blockData);
Than this is the Flash_Write_Start function:
void Flash_Write_Start( uint32_t totalBlockNumber, uint32_t blockNumber, uint32_t packet_length, uint8_t * blockData)
{
HAL_StatusTypeDef errorCheck = 1;
uint32_t bankActive;
if(fwFrameCounter == blockNumber)
{
errorCheck = FLASH_If_Write(Flash_Write_Address, blockData, packet_length);
}
if(errorCheck != FLASHIF_OK)
{
SerialPrint("FLASH ERROR\n");
}
Not every time but I have a hardfault, when code comes in FLASH_If_Write(Flash_Write_Address, blockData, packet_length); function. What is the reason for ?
FLASHIF_StatusTypeDef FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
{
FLASHIF_StatusTypeDef status ;
HAL_StatusTypeDef halErrorFlag;
/* Unlock the Flash to enable the flash control register access *************/
if (HAL_FLASH_Unlock() != HAL_OK)
{
return FLASHIF_CRCKO;
}
uint32_t i ;
status = FLASHIF_OK;
/* DataLength must be a multiple of 32 bit */
for ( i = 0U; (i < (length >> 2U)) && (destination <= (USER_FLASH_END_ADDRESS - 4U)); i++) //
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (destination + (i * 4U)), *(uint32_t *)(p_source + i)) == HAL_OK)
{
/* Check the written value */
if (*(__IO uint32_t *)(destination + (i * 4U)) != *(uint32_t *)(p_source + i))
{
status = FLASHIF_WRITINGCTRL_ERROR;
}
/* Increment FLASH destination address */
// destination += 4;
}
else
{
/* Error occurred while writing data in Flash memory */
status = FLASHIF_WRITING_ERROR;
break;
}
// SerialPrint(" 4 \n");
if (status != FLASHIF_OK)
{
break;
}
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
halErrorFlag = HAL_FLASH_Lock();
if( halErrorFlag != HAL_OK)
{
}
return status;
}

How to read sei unregistered user data from ffmpeg in H264?

First, I set the user_data to video by bsf. For example,
ffmpeg -i dump.flv -c:v copy -bsf:v h264_metadata=sei_user_data='086f3693-b7b3-4f2c-9653-21492feee5b8+hello' dump_sei.flv
Ant then I use the api to read sei unregistered_user_data by ffmpeg after h264 encode, but I didn't get it.
// avcodec_send_packet
// avcodec_receive_frame
// ...
H264Context *h = m_pVidDecodeCtx->priv_data;
H264SEIContext sei = h->sei;
H264SEIUnregistered unregistered = sei.unregistered;
if (unregistered.buf_ref != NULL)
{
AVBufferRef *buf = *(unregistered.buf_ref);
if (buf != NULL && buf->buffer != NULL)
{
printf("sei data: %s\n", buf->buffer);
}
}
The version of ffmpeg is v4.4.
A great treasure where you can find your answers to all your questions about SEI is h264_sei.c file . (that exist in libavcodec folder)
static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size)
{
int flag;
if (size-- < 1)
return AVERROR_INVALIDDATA;
skip_bits(gb, 1); // 0
flag = get_bits(gb, 1); // active_format_flag
skip_bits(gb, 6); // reserved
if (flag) {
if (size-- < 1)
return AVERROR_INVALIDDATA;
skip_bits(gb, 4); // reserved
h->active_format_description = get_bits(gb, 4);
h->present = 1;
}
return 0;
}
static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h,
GetBitContext *gb, void *logctx,
int size)
{
if (size < 3)
return AVERROR(EINVAL);
return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size);
}
static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb,
void *logctx, int size)
{
int country_code, provider_code;
if (size < 3)
return AVERROR_INVALIDDATA;
size -= 3;
country_code = get_bits(gb, 8); // itu_t_t35_country_code
if (country_code == 0xFF) {
if (size < 1)
return AVERROR_INVALIDDATA;
skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte
size--;
}
if (country_code != 0xB5) { // usa_country_code
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
country_code);
return 0;
}
/* itu_t_t35_payload_byte follows */
provider_code = get_bits(gb, 16);
switch (provider_code) {
case 0x31: { // atsc_provider_code
uint32_t user_identifier;
if (size < 4)
return AVERROR_INVALIDDATA;
size -= 4;
user_identifier = get_bits_long(gb, 32);
switch (user_identifier) {
case MKBETAG('D', 'T', 'G', '1'): // afd_data
return decode_registered_user_data_afd(&h->afd, gb, size);
case MKBETAG('G', 'A', '9', '4'): // closed captions
return decode_registered_user_data_closed_caption(&h->a53_caption, gb,
logctx, size);
default:
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n",
user_identifier);
break;
}
break;
}
default:
av_log(logctx, AV_LOG_VERBOSE,
"Unsupported User Data Registered ITU-T T35 SEI message (provider_code = %d)\n",
provider_code);
break;
}
return 0;
}
static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb,
void *logctx, int size)
{
uint8_t *user_data;
int e, build, i;
AVBufferRef *buf_ref, **tmp;
if (size < 16 || size >= INT_MAX - 1)
return AVERROR_INVALIDDATA;
tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref));
if (!tmp)
return AVERROR(ENOMEM);
h->buf_ref = tmp;
buf_ref = av_buffer_alloc(size + 1);
if (!buf_ref)
return AVERROR(ENOMEM);
user_data = buf_ref->data;
for (i = 0; i < size; i++)
user_data[i] = get_bits(gb, 8);
user_data[i] = 0;
buf_ref->size = size;
h->buf_ref[h->nb_buf_ref++] = buf_ref;
e = sscanf(user_data + 16, "x264 - core %d", &build);
if (e == 1 && build > 0)
h->x264_build = build;
if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))
h->x264_build = 67;
return 0;
}

Playing audio with stb_vorbis and SDL2 cuts off

No matter what what audio file I use, it always cuts off about a fourth of the way through. I have a feeling it's because I'm casting the decoded audio to a Uint8*, but if I don't, the audio plays really fast and it still only plays about half of the file. Also, using SDL_MixAudio instead of SDL_memcpy causes a bunch of copies of the sound to play over each other for some reason.
Uint8* audio_pos;
Uint32 audio_len;
void audioCallback(void* userdata, Uint8* stream, int len) {
if (audio_len == 0) return;
len = (len > audio_len ? audio_len : len);
SDL_memcpy(stream, audio_pos, len);
audio_pos += len;
audio_len -= len;
}
int main(int argc, char *argv[]) {
...
short* decoded;
int channels, rate, len;
len = stb_vorbis_decode_filename(RealPath("music.ogg").c_str(), &channels, &rate, &decoded);
SDL_AudioSpec spec;
spec.freq = rate;
spec.format = AUDIO_S16;
spec.channels = channels;
spec.samples = 2048;
spec.callback = audioCallback;
spec.userdata = NULL;
audio_pos = (Uint8*)decoded;
audio_len = len;
if (SDL_OpenAudio(&spec, NULL) < 0) {
std::cout << "failed to open audio device: " << SDL_GetError() << '\n';
SDL_GL_DeleteContext(context);
SDL_Quit();
return -1;
}
SDL_PauseAudio(0);
SDL_Event windowEvt;
while (true) {
if (audio_len == 0) break;
if (SDL_PollEvent(&windowEvt)) {
if (windowEvt.type == SDL_QUIT) break;
if (windowEvt.type == SDL_KEYUP && windowEvt.key.keysym.sym == SDLK_ESCAPE) break;
}
SDL_GL_SwapWindow(window);
}
...
}
stb_vorbis_decode_filename returns the "number of samples decoded," which is respect to an int16, and doesn't include the channel factor.
You're looking for:
int32 length = stb_vorbis_decode_filename("thing.ogg", &channels, &rate, &decoded);
int32 audio_length = length * channels * (sizeof(int16) / sizeof(uint8));
With respect to SDL_MixAudio vs SDL_memcpy for sound overlap, you need to explicitly clear the stream with a silence value. For example, SDL_memset when you enter the SDL audio callback.
void audioCallback(void* userdata, Uint8* stream, int len)
{
SDL_memset(stream, 0, len);// silence the stream
if (audio_len == 0) return;
len = (len > audio_len ? audio_len : len);
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);// this takes a volume argument
audio_pos += len;
audio_len -= len;
}
The zero passed to SDL_memset should be the same silence value you created in SDL_AudioSpec, when calling SDL_OpenAudioDevice.

AF_LINK not defined in bits/socket.h and sys/socket.h

I am writing a code to read the MAC address from the interface for listing the interface and it MAC address as I am not able to find the AF_LINK definition in either of the socket.h files.
As per internet resources i should see below:
#define AF_LINK 18 /* Link layer interface */
But my bits/socket.h contains:
#define PF_ASH 18 /* Ash. */
.
.
#define AF_ASH PF_ASH
Should I be using PF_ASH in place of AF_LINK?
Here is the part of my code that uses AF_LINK:
if ((family == AF_LINK) && (ifa->ifa_name[0] == 'e')) {
//This is for extracting interface number from interface name//
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
Full code:
/*
* ethernetsocket.c
*
* Created on: Feb 25, 2015
* Author: tsp3859
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bits/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <ifaddrs.h>
#define MY_DEST_MAC0 0xff
#define MY_DEST_MAC1 0xff
#define MY_DEST_MAC2 0xff
#define MY_DEST_MAC3 0xff
#define MY_DEST_MAC4 0xff
#define MY_DEST_MAC5 0xff
// Source Ethernet interface
#define DEFAULT_InterFace "eth0"
#define DEFAULT_PayLoad "1.1.10"
// Allocating size to different containers
#define MAX_FRAME_SIZE 1024
#define MAX_PAYLD_SIZE 1000
#define HEADER_SIZE 14
int payLoad_Size = -1;
int frame_Size = -1;
int main(int argc, char *argv[]) {
int sockfd;
struct ifreq if_idx; // destination ethernet (optional)
struct ifreq if_mac; // destination mac address
int tx_len = 0; // header counter
char ifName[IFNAMSIZ]; // interface name
uint8_t header[HEADER_SIZE]; // ethernet header
char dummy_Payload[MAX_PAYLD_SIZE];
int if_num; // interface number, used for genarating VID
/*
* Run as one of the following command
* 1. ./a.out
* 2 ./a.out eth3
* 3. ./a.out eth4 PayLoad
*/
// Get Ethernet interface name from command line (optional)
if (argc > 1) {
if (argc == 2) {
strcpy(ifName, argv[1]);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
if (argc == 3) {
strcpy(ifName, argv[1]);
if (strlen(argv[2]) > 1000) {
memcpy(dummy_Payload, argv[2], MAX_PAYLD_SIZE);
} else
strcpy(dummy_Payload, argv[2]);
}
} else {
// Default case: All fields are optional
if (argc < 2) {
strcpy(ifName, DEFAULT_InterFace);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
}
//Getting interface number
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
int k = 1; // Interface SNo.
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if ((family == AF_INET || family == AF_INET6) && (ifa->ifa_name[0] == 'e')) {
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
}
// Setting frame size
payLoad_Size = strlen(dummy_Payload);
// Setting payload, contains VID
char payLoad[payLoad_Size];
//memcpy(payLoad,dummy_Payload,payLoad_Size);
int len=0;
payLoad[len++]=1;
payLoad[len++]=1;
payLoad[len]=10;
frame_Size = HEADER_SIZE + strlen(payLoad);
//printf("Payload size is %d\n ", payLoad_Size);
printf("Frame size is %d\n ", frame_Size);
printf("Payload size is %d\n\n ", strlen(payLoad));
payLoad_Size=strlen(payLoad);
// creating frame
uint8_t frame[frame_Size];
struct ether_header *eh = (struct ether_header *) header;
struct sockaddr_ll socket_address;
// Open RAW socket to send on
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("Socket Error");
}
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX - Misprint Compatibility");
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror(
"SIOCGIFHWADDR - Either interface is not correct or disconnected");
// Initializing the Ethernet Header
memset(header, 0, HEADER_SIZE);
// Print-test initial header
printf("Zeros: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
header[0], header[1], header[2], header[3], header[4], header[5],
header[6], header[7], header[8], header[9], header[10], header[11],
header[12], header[13]);
/*
* Ethernet Header - 14 bytes
*
* 6 bytes - Source MAC Address
* 6 bytes - Destination MAC Address
* 2 bytes - EtherType
*
*/
eh->ether_shost[0] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *) &if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
eh->ether_type = htons(0x8010);
tx_len += sizeof(struct ether_header);
// Copying header to frame
memcpy(frame, header, 14);
// Copying payLoad to frame
//printf("Payload: %d\n", payLoad[1]);
memcpy(frame + 14, payLoad, strlen(payLoad));
// Printing initial frame
printf(" Frame: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
frame[0], frame[1], frame[2], frame[3], frame[4], frame[5],
frame[6], frame[7], frame[8], frame[9], frame[10], frame[11],
frame[12], frame[13]);
// Printing payLoad
printf("Payload: %d.%d.%d\n", frame[14],frame[15],frame[16]);
// Index of the network device
socket_address.sll_ifindex = if_idx.ifr_ifindex;
// Address length - 6 bytes
socket_address.sll_halen = ETH_ALEN;
// Destination MAC Address
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
// Send packet
if (sendto(sockfd, frame, tx_len + strlen(payLoad), 0,
(struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
return 0;
}