i faced a problem with Multi-UDP Socket.
Now I have a PC(192.168.58.200), and 3 MPU(STM32F4)(192.168.85.100~102).
and I Conncected RS232 With MPU.
When MPU got a messasge, it returns just 'X', and print out same thing with RS232, so i can distinguish when PC can not send message and when MPU can get a message but PC can not recieve the message.
below is my code, Especially "UdpClient[c].Write( TempStr, strlen(TempStr));" doesnt work.
when it send mesage, only one MPU can get a message, and keep reciving 30~40 sec, some times changed other MPU.
1:1 is fine, but problem is more 2 Peer. please share your experiences.
// udpclient.cpp
#include <stdio.h>
#include "UDPCLIENT.h"
#include "UDPServer.h"
struct sPeer
{
char IP[64];
int Port;
};
#define CUR_MPU 3
#define MAX_MPU 16
sPeer Peer[MAX_MPU];
unsigned long _stdcall ReadThread(void *Param)
{
UDPSERVERSOCKET UDPSocket;
int ID = (int)Param;
printf("Server ID %d\n", ID);
UDPSocket.Open(Peer[ID].Port);
while (1)
{
char ReadBuffer[1024];
char Addr[32];
UDPSocket.Read(Addr, ReadBuffer, 1024);
printf("%s>%s\n", Addr, ReadBuffer);
}
UDPSocket.Close();
return 0;
}
int main()
{
sprintf(Peer[0].IP, "192.168.58.100"); Peer[0].Port = 7726;
sprintf(Peer[1].IP, "192.168.58.101"); Peer[1].Port = 7727;
sprintf(Peer[2].IP, "192.168.58.102"); Peer[2].Port = 7728;
///////////////////////쓰레드를 연다./////////////////
for (int c = 0; c < CUR_MPU; c++)
{
DWORD ID;
HANDLE thread01 = CreateThread( NULL,//보안 속성
0,//스택의 크기
ReadThread,//함수
(void *)c,//인자
0,//생성플러그
&ID);// 아이디
}
UDPCLIENTSOCKET UdpClient[CUR_MPU];
for (int c = 0; c < CUR_MPU; c++)
{
UdpClient[c].Open(Peer[c].IP, Peer[c].Port);
}
while (1)
{
char TempStr[1024];
printf("보낼 메시지 ---");
scanf("%s", TempStr);
for (int c = 0; c < CUR_MPU; c++)
{
UdpClient[c].Write( TempStr, strlen(TempStr));
}
}
for (int c = 0; c < CUR_MPU; c++)
UdpClient[c].Close();
return 0;
}
Cleint.cpp
#include "UDPCLIENT.h"
int UDPCLIENTSOCKET::Open(char *Address , int Port)
{
unsigned int addr;
int nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData);
if (nRtn != 0) {
perror("WSAStartup 오류\n");
return -1;
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("소켓 오류\n");
WSACleanup();
return -2;
}
lpHostEnt = gethostbyname(Address);
if (lpHostEnt == NULL) {
addr = inet_addr(Address);
lpHostEnt = gethostbyaddr((char *)&addr, 4, AF_INET);
if (lpHostEnt == NULL) {
perror("서버를 찾을 수 없습니다.\n");
_getch();
return -3;
}
}
memset(&addrin, 0, sizeof(addrin));
memcpy(&(addrin.sin_addr),
lpHostEnt->h_addr_list[0],
lpHostEnt->h_length);
addrin.sin_port = htons(Port);
addrin.sin_family = AF_INET;
//addrin.sin_addr.s_addr =
// *((unsigned long *)lpHostEnt->h_addr);
return 1;
}
void UDPCLIENTSOCKET::Close()
{
closesocket(s);
WSACleanup();
}
int UDPCLIENTSOCKET::Write(char *Address, int Port, char *Buffer, int Size)
{
unsigned int addr;
lpHostEnt = gethostbyname(Address);
if (lpHostEnt == NULL) {
addr = inet_addr(Address);
lpHostEnt = gethostbyaddr((char *)&addr, 4, AF_INET);
if (lpHostEnt == NULL) {
perror("서버를 찾을 수 없습니다.\n");
_getch();
return -3;
}
}
memset(&addrin, 0, sizeof(addrin));
memcpy(&(addrin.sin_addr),
lpHostEnt->h_addr_list[0],
lpHostEnt->h_length);
addrin.sin_port = htons(Port);
addrin.sin_family = AF_INET;
int nRtn = sendto(s, Buffer, Size, 0,
(LPSOCKADDR)&addrin, sizeof(addrin));
return nRtn;
}
int UDPCLIENTSOCKET::Write(char *Buffer, int Size)
{
int nRtn = sendto(s, Buffer, Size, 0,
(LPSOCKADDR)&addrin, sizeof(addrin));
return nRtn;
}
Server.cpp
#include "UDPServer.h"
int UDPSERVERSOCKET::Open(u_short uport)
{
int nRtn;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
perror("WSAStartup Error\n");
return -1;
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket 오류\n");
WSACleanup();
return -2;
}
memset(&addrin, 0, sizeof(addrin));
addrin.sin_port = htons(uport);
addrin.sin_family = AF_INET;
addrin.sin_addr.s_addr = htonl(INADDR_ANY);
nRtn = bind(s, (LPSOCKADDR)&addrin, (int)sizeof(addrin));
if (nRtn == SOCKET_ERROR) {
perror("bind 오류\n");
closesocket(s);
WSACleanup();
return -3;
}
return 1;
}
int UDPSERVERSOCKET::Read(char *Addr, char *Buffer, int Length)
{
int fromlen = (int)sizeof(from);
int nRtn = recvfrom(s,
Buffer,
Length -1,
0,
(SOCKADDR *)&from,
&fromlen);
if (nRtn == SOCKET_ERROR)
{
Addr[0] = 0;
perror("recvform 오류\n");
closesocket(s);
WSACleanup();
return -4;
}
strcpy(Addr, inet_ntoa(from.sin_addr));
Buffer[nRtn] = '\0';
return 1;
}
int UDPSERVERSOCKET::Close()
{
closesocket(s);
WSACleanup();
printf("WSACleanup 완료\n");
return 1;
}
void UDPSERVERSOCKET::ShowErrorMessage(int i)
{
}
void UDPSERVERSOCKET::ReturnClientIP(char *Buffer)
{
}
Related
Why does my structure assignment fail in C language?
I have a class A: define a structure
typedef struct{
int sockfd;
on_av_frame_cb av_frame_cb;
on_av_frame_cb rtp_cb;
on_error_cb error_cb;
uint8_t *p_buf;
uint8_t *v_buf;
uint8_t *a_buf;
int rtp_flag;
}udp_client_t;
Then I call in class B:
static udp_client_t client;
int jldv_create_client(int src_port,int port ,const char *dst_ip){
udp_client_t *udpClient = &client;
assert(udpClient != NULL);
const char *c_ip = dst_ip;
memset(udpClient, 0, sizeof(udp_client_t));
int ret = create_client(src_port, port, c_ip, &udpClient);
if (ret != 0) {
goto err_output;
}
udpClient->av_frame_cb = (on_av_frame_cb )onVideoFrame;
udpClient->error_cb = on_error;
if (rtp_create(&udpClient) < 0) { ///above problem
goto err_output;
}
printf("rtp_client:%d \n",udpClient->rtp_flag);
return 0;
err_output:
destroy_client(udpClient);
return -1;
}
In the above problem, I used the C class method:
int rtp_create(udp_client_t **data)
{
logi("%s", __func__);
udp_client_t *udpClient = *data;
if(udpClient)
{
udpClient->rtp_flag = 1;
memset(&rtp_cxt, 0, sizeof(rtp_context_t));
int ret = init_server();
if (ret < 0)
{
return -1;
}
rtp_cxt.nalu = alloc_nalu(MAX_FRAME_SIZE);//
if (!rtp_cxt.nalu)
{
loge("alloc nalu failed");
return -2;
}
}
else
{
loge("%s: data is null", __func__);
return -3;
}
printf("udpClient after==>%d \n",udpClient->rtp_flag);
return 0;
}
However, the result of printing is:
udpClient after==>1
rtp_client:0
supplement:
int create_client(int src_port, int dst_port, const char *dst_ip, udp_client_t **client)
{
udp_client_t *udpClient = *client;
assert(udpClient != NULL);
memset(udpClient, 0, sizeof(udp_client_t));
printf("create_client:%p\n",udpClient);
udpClient->port = src_port;
if (pthread_create(&udpClient->recv_tid, NULL, udp_receiver_runnable, (void *) udpClient) != 0)
{
loge("Failed to start new thread");
goto err_output;
}
return 0;
err_output:
memset(udpClient, 0, sizeof(udp_client_t));
return -10;
}
Why is that? Did i use something wrong?
I am trying to read data from a pendrive connected through USB on Windows using libusb and C-programming. I am able to list out my USB connections, but I couldn't connect to one and transfer data from the USB in to my computer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libusb.h"
#define BULK_EP_OUT 0x63
#define BULK_EP_IN 0x08
int interface_ref = 0;
int alt_interface, interface_number;
int print_configuration(struct libusb_device_handle *hDevice, struct libusb_config_descriptor *config)
{
char *data;
int index;
data = (char *)malloc(512);
memset(data, 0, 512);
index = config->iConfiguration;
libusb_get_string_descriptor_ascii(hDevice, index, data, 512);
printf("\nInterface Descriptors: ");
printf("\n\tNumber of Interfaces: %d", config->bNumInterfaces);
printf("\n\tLength: %d", config->bLength);
printf("\n\tDesc_Type: %d", config->bDescriptorType);
printf("\n\tConfig_index: %d", config->iConfiguration);
printf("\n\tTotal length: %lu", config->wTotalLength);
printf("\n\tConfiguration Value: %d", config->bConfigurationValue);
printf("\n\tConfiguration Attributes: %d", config->bmAttributes);
printf("\n\tMaxPower(mA): %d\n", config->MaxPower);
free(data);
data = NULL;
return 0;
}
struct libusb_endpoint_descriptor* active_config(struct libusb_device *dev, struct libusb_device_handle *handle)
{
struct libusb_device_handle *hDevice_req;
struct libusb_config_descriptor *config;
struct libusb_endpoint_descriptor *endpoint;
int altsetting_index, interface_index=0, ret_active;
int i, ret_print;
hDevice_req = handle;
ret_active = libusb_get_active_config_descriptor(dev, &config);
ret_print = print_configuration(hDevice_req, config);
for (interface_index=0;interface_index<config->bNumInterfaces;interface_index++)
{
const struct libusb_interface *iface = &config->interface[interface_index];
for (altsetting_index=0; altsetting_index<iface->num_altsetting; altsetting_index++)
{
const struct libusb_interface_descriptor *altsetting = &iface->altsetting[altsetting_index];
int endpoint_index;
for(endpoint_index=0; endpoint_index<altsetting->bNumEndpoints; endpoint_index++)
{
const struct libusb_endpoint_desriptor *ep = &altsetting->endpoint[endpoint_index];
endpoint = ep;
alt_interface = altsetting->bAlternateSetting;
interface_number = altsetting->bInterfaceNumber;
}
printf("\nEndPoint Descriptors: ");
printf("\n\tSize of EndPoint Descriptor: %d", endpoint->bLength);
printf("\n\tType of Descriptor: %d", endpoint->bDescriptorType);
printf("\n\tEndpoint Address: 0x0%x", endpoint->bEndpointAddress);
printf("\n\tMaximum Packet Size: %x", endpoint->wMaxPacketSize);
printf("\n\tAttributes applied to Endpoint: %d", endpoint->bmAttributes);
printf("\n\tInterval for Polling for data Tranfer: %d\n", endpoint->bInterval);
}
}
libusb_free_config_descriptor(NULL);
return endpoint;
}
int main(void)
{
int r = 1, found1;
struct libusb_device **devs;
struct libusb_device_handle *handle = NULL, *hDevice_expected = NULL;
struct libusb_device *dev, *dev_expected;
struct libusb_device_descriptor desc;
struct libusb_endpoint_descriptor *epdesc;
struct libusb_interface_descriptor *intdesc;
libusb_context *context = NULL;
ssize_t cnt;
int e = 0, config2;
int i = 0, index;
char str1[64], str2[64];
char found = 0;
// Init libusb
r = libusb_init(NULL);
if(r < 0)
{
printf("\nFailed to initialise libusb\n");
return 1;
}
else
printf("\nInit successful!\n");
// Get a list of USB devices
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
{
printf("\nThere are no USB devices on the bus\n");
return -1;
}
printf("\nDevice count: %d\n-------------------------------\n", cnt);
while ((dev = devs[i++]) > 0)
{
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
printf("Failed to get device descriptor\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
e = libusb_open(dev, &handle);
if (e < 0)
{
printf("Error opening device\n");
printf(e);
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nDevice Descriptors: ");
printf("\n\tVendor ID: %x", desc.idVendor);
printf("\n\tProduct ID: %x", desc.idProduct);
printf("\n\tSerial Number: %x", desc.iSerialNumber);
printf("\n\tSize of Device Descriptor: %d", desc.bLength);
printf("\n\tType of Descriptor: %d", desc.bDescriptorType);
printf("\n\tUSB Specification Release Number: %d", desc.bcdUSB);
printf("\n\tDevice Release Number: %d", desc.bcdDevice);
printf("\n\tDevice Class: %d", desc.bDeviceClass);
printf("\n\tDevice Sub-Class: %d", desc.bDeviceSubClass);
printf("\n\tDevice Protocol: %d", desc.bDeviceProtocol);
printf("\n\tMax. Packet Size: %d", desc.bMaxPacketSize0);
printf("\n\tNumber of Configurations: %d\n", desc.bNumConfigurations);
e = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, (unsigned char*) str1, sizeof(str1));
if (e < 0)
{
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nManufactured: %s", str1);
e = libusb_get_string_descriptor_ascii(handle, desc.iProduct, (unsigned char*) str2, sizeof(str2));
if(e < 0)
{
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nProduct: %s", str2);
printf("\n----------------------------------------");
if(desc.idVendor == 0x0781 && desc.idProduct == 0x5567)
{
found1 = 1;
break;
}
}//end of while
if (found1 == 0)
{
printf("\nDevice NOT found\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return 1;
}
else
{
printf("\nDevice found");
dev_expected = dev;
hDevice_expected = handle;
}
e = libusb_get_configuration(handle, &config2);
if (e!=0)
{
printf("\n***Error in libusb_get_configuration\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
printf("\nConfigured value: %d", config2);
if (config2 != 1)
{
libusb_set_configuration(handle, 1);
if(e!=0)
{
printf("Error in libusb_set_configuration\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
else
printf("\nDevice is in configured state!");
}
libusb_free_device_list(devs, 1);
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
}
e = libusb_claim_interface(handle, 0);
if (e < 0)
{
printf("\nCannot Claim Interface");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
else
printf("\nClaimed Interface\n");
active_config(dev_expected, hDevice_expected);
char *my_string, *my_string1;
int transferred = 0;
int received = 0;
int length = 0;
int nbytes = 256;
my_string = (char *)malloc(nbytes + 1);
my_string1 = (char *)malloc(nbytes + 1);
memset(my_string, '\0', 64);
memset(my_string1, '\0', 64);
strcpy(my_string, "Prasad Divesd");
length = strlen(my_string);
printf("\nTo be sent: %s", my_string);
for(i = 0; i < length; i++)
{
e = libusb_bulk_transfer(handle, BULK_EP_OUT, my_string1, 64, &received, 0); //64: Max Packet Length
if(e == 0)
{
printf("\nReceived: ");
printf("%c", my_string1[i]);
_sleep(1);
}
else
{
printf("\nError in read! e = %d and received = %d\n", e, received);
return -1;
}
}
e = libusb_release_interface(handle, 0);
libusb_close(handle);
libusb_exit(NULL);
printf("\n");
return 0;
}
The code from Read/write on a pen drive using libusb: libusb_bulk_transfer() is for Linux. The sequence below is to detach the kernel driver in Linux.
This is done to be able write a bulk transfer to the USB mass storage device (pendrive). In Linux this is necessary, in Windows not because in Windows libusb has its own driver:
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
}
So you have to delete at least this code.
Then notice that libusb on Windows has some limitations, see https://github.com/libusb/libusb/wiki/Windows.
If you want to debug programs use a debugger like WinDbg (Viewing the Call Stack in WinDbg) and get a stack trace (Windows Debuggers: Part 1: A WinDbg Tutorial and Viewing the Call Stack in WinDbg)
For more information on USB, see USB in a NutShell.
Beside this the code you posted should work (when removing the Linux-specific lines, etc.).
I am finding out usb mass storage related information using libusb library.
But don't know how to get usb mass storage size?
My tryout is:
void printdev(libusb_device *dev);
int main()
{
libusb_device **devs;
libusb_context *ctx = NULL; //a libusb session
int r;
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize a library session
if(r < 0)
{
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0)
{
cout<<"Get Device Error"<<endl; //there was an error
}
cout<<cnt<<" Devices in list."<<endl; //print total number of usb devices
int i;
for(i = 0; i < cnt; i++)
{
printdev(devs[i]);
}
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
libusb_exit(ctx); //close the session
return 0;
}
void printdev(libusb_device *dev)
{
libusb_device_descriptor desc;
libusb_config_descriptor *conDesc;
char szBuffer[256] = {0};
unsigned char strDesc[256];
libusb_device_handle *devHandle = NULL;
int retVal;
__int64 i64Temp;
DWORD dwProdId;
DWORD dwProdId1;
i64Temp = 13888;
dwProdId = (DWORD)i64Temp;
retVal = libusb_open (dev, &devHandle);
if (retVal != LIBUSB_SUCCESS)
return;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
cout<<"failed to get device descriptor"<<endl;
return;
}
r = libusb_get_config_descriptor(dev, 0, &conDesc);
printf("Interface Class = %d\n", conDesc->interface->altsetting->bInterfaceClass);
cout<<"Number of possible configurations: "<<(int)desc.bNumConfigurations<<" ";
// cout<<"Device Class: "<<desc.bDeviceClass<<endl;
// cout<<"Device Class: "<<desc.bDeviceSubClass<<endl;
printf("Class = %d\n", desc.bDeviceClass);
cout<<"VendorID: "<<desc.idVendor<<endl;
cout<<"ProductID: "<<desc.idProduct<<endl;
dwProdId1 = (DWORD)desc.idProduct;
if (dwProdId1 == dwProdId)
{
printf("in if\n");
}
else
{
printf("in else\n");
}
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iManufacturer, strDesc, 256);
printf ("Manufacturer: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iSerialNumber, strDesc, 256);
printf ("SerialNumber: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iProduct, strDesc, 256);
printf ("Product: %s\n", strDesc);
printf("\n\n");
}
I get a triangle demo from internet. It works on my ubuntu13.04 virtual machine,but it doesn't work on my ubuntu12.04 virtual machine.All of my two vritual machines installed libgles2-mesa-dev(apt-get).The only diffrenet is:the ubuntu12.04 glesv2 is based on mesa-8.0 and the ubuntu13.04 glesv2 is based on mesa-9.
My code:
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <X11/Xlib.h>
#define VERTEX_ARRAY 0
EGLDisplay eglDisplay = 0;
EGLConfig eglConfig = 0;
EGLSurface eglSurface = 0;
EGLContext eglContext = 0;
EGLNativeWindowType eglWindow = 0;
bool TestEGLError()
{
EGLint iErr = eglGetError();
if (iErr != EGL_SUCCESS)
{
return false;
}
return true;
}
bool CreateEGLContext()
{
eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);
EGLint iMajorVersion, iMinorVersion;
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
{
return false;
}
const EGLint pi32ConfigAttribs[] =
{
EGL_LEVEL, 0,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NATIVE_RENDERABLE, EGL_FALSE,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_NONE
};
EGLint config16bpp[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_NONE
};
int iConfigs;
if (!eglChooseConfig(eglDisplay,config16bpp, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
return false;
}
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL);
if(eglSurface == EGL_NO_SURFACE)
{
eglGetError(); // Clear error
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL);
}
if (!TestEGLError())
{
return false;
}
eglBindAPI(EGL_OPENGL_ES_API);
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
if (!TestEGLError())
{
return false;
}
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!TestEGLError())
{
return false;
}
return true;
}
bool Render()
{
bool bRet = false;
float pfIdentity[] =
{
1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f
};
char szFragShaderSrc[] = {"\
void main (void)\
{\
gl_FragColor = vec4(1.0, 1.0, 0.66 ,1.0);\
}"};
char szVertShaderSrc[] = {"\
attribute highp vec4 myVertex;\
uniform mediump mat4 myPMVMatrix;\
void main(void)\
{\
gl_Position = myPMVMatrix * myVertex;\
}"};
char * pszFragShader = (char *)szFragShaderSrc;
char * pszVertShader = (char *)szVertShaderSrc;
GLuint uiFragShader = 0;
GLuint uiVertShader = 0;
GLuint uiProgramObject = 0;
GLint bShaderCompiled;
GLint bLinked;
GLuint ui32Vbo = 0;
GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position
0.4f ,-0.4f,0.0f,
0.0f ,0.4f ,0.0f};
int i32InfoLogLength, i32CharsWritten;
char* pszInfoLog = NULL;
int i32Location = 0;
unsigned int uiSize = 0;
uiFragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(uiFragShader, 1, (const char**)&pszFragShader, NULL);
glCompileShader(uiFragShader);
glGetShaderiv(uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled);
if (!bShaderCompiled)
{
glGetShaderiv(uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetShaderInfoLog(uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
uiVertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(uiVertShader, 1, (const char**)&pszVertShader, NULL);
glCompileShader(uiVertShader);
glGetShaderiv(uiVertShader, GL_COMPILE_STATUS, &bShaderCompiled);
if (!bShaderCompiled)
{
glGetShaderiv(uiVertShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetShaderInfoLog(uiVertShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
uiProgramObject = glCreateProgram();
glAttachShader(uiProgramObject, uiFragShader);
glAttachShader(uiProgramObject, uiVertShader);
glBindAttribLocation(uiProgramObject, VERTEX_ARRAY, "myVertex");
glLinkProgram(uiProgramObject);
glGetProgramiv(uiProgramObject, GL_LINK_STATUS, &bLinked);
if (!bLinked)
{
glGetProgramiv(uiProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
pszInfoLog = new char[i32InfoLogLength];
glGetProgramInfoLog(uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
delete[] pszInfoLog;
goto cleanup;
}
glUseProgram(uiProgramObject);
glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
glGenBuffers(1, &ui32Vbo);
glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex))
glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW);
{
glClear(GL_COLOR_BUFFER_BIT);
i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix");
glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(eglDisplay, eglSurface);
}
bRet = true;
cleanup:
if (uiProgramObject)
glDeleteProgram(uiProgramObject);
if (uiFragShader)
glDeleteShader(uiFragShader);
if (uiVertShader)
glDeleteShader(uiVertShader);
// Delete the VBO as it is no longer needed
if (ui32Vbo)
glDeleteBuffers(1, &ui32Vbo);
return bRet;
}
int main(int argc ,char* argv[])
{
unsigned int uiHeight = 800;
unsigned int uiWidth = 480;
int screen;
Display *x_display;
Window root_window;
x_display = XOpenDisplay ( NULL ); // open the standard display (the primary screen)
if ( x_display == NULL ) {
printf ("cannot connect to X server");
return false;
}
screen = DefaultScreen(x_display);
root_window = RootWindow(x_display,screen);
static int Hnd = XCreateSimpleWindow(x_display, root_window,0,0,800,480,0,0,0);
eglWindow = (EGLNativeWindowType)Hnd;
if (!eglWindow)
{
printf("Failed to create X window.\n");
return false;
}
XUndefineCursor(x_display, eglWindow);
XMapRaised(x_display, eglWindow);
XFlush(x_display);
CreateEGLContext();
while(1)
{
Render();
usleep(100000);
}
return 0;
}
I am trying to perform read and write operations on a pen drive.
Details: Vendor ID: 8564 and Product ID: 1000. It is a Transcend JetFlash mass storage device.
I am keen to know that whether it is possible to achieve a read/write on a pen drive. If it is, then is it going to happen the way I have tried in the code provided below.
I have learnt the methods to get the device id, product id and endpoint addresses. This is what I have implemented.
Here the device is getting acknowledged and opened. And, even the interface claims it is successful.
But bulk transfer functions return -1.
What is the explanation?
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include </usr/include/libusb-1.0/libusb.h>
#define BULK_EP_OUT 0x82
#define BULK_EP_IN 0x02
int main(void)
{
int r = 0, e = 0;
struct libusb_device_handle *handle = NULL;
struct libusb_device **devs;
struct libusb_device *dev;
struct libusb_device_descriptor desc;
char str1[256], str2[256];
/* Init libusb */
r = libusb_init(NULL);
if (r < 0)
{
printf("\nfailed to initialise libusb\n");
return 1;
}
handle = libusb_open_device_with_vid_pid(NULL, 0x8564, 0x1000);
if(handle == NULL)
{
printf("\nError in device opening!");
}
else
printf("\nDevice Opened");
// Tell libusb to use the CONFIGNUM configuration of the device
libusb_set_configuration(handle, 1);
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
}
e = libusb_claim_interface(handle, 0);
if(e < 0)
{
printf("\nCannot Claim Interface");
}
else
printf("\nClaimed Interface");
/* Communicate */
int bytes_read;
int nbytes = 256;
unsigned char *my_string, *my_string1;
int transferred = 0;
my_string = (unsigned char *) malloc (nbytes + 1);
my_string1 = (unsigned char *) malloc (nbytes + 1);
strcpy(my_string, "divesd");
printf("\nTo be sent : %s", my_string);
e = libusb_bulk_transfer(handle, BULK_EP_OUT, my_string, bytes_read, &transferred, 5000);
printf("\nXfer returned with %d", e);
printf("\nSent %d bytes with string: %s\n", transferred, my_string);
libusb_bulk_transfer(handle, BULK_EP_IN, my_string1, 256, &transferred, 5000);
printf("\nXfer returned with %d", e); //It returns -1... This is an error, I guess.
printf("\nReceived %d bytes with string: %s\n", transferred, my_string1);
e = libusb_release_interface(handle, 0);
libusb_close(handle);
libusb_exit(NULL);
return 0;
}
Try the code given below and it should work on LPC2148. I have tested this with an LPC2148 configured to receive an interrupt from USB after a write happens (from user-space) and the RTC starts running.
Answering to your question whether it involves a kernel driver in read/write or not: As far as I have studied, you have to detach the kernel driver and claim the interface using libusb APIs. Though I am not sure whether it can be done without detaching it or not.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include </usr/local/include/libusb-1.0/libusb.h>
#define BULK_EP_OUT 0x82
#define BULK_EP_IN 0x08
int interface_ref = 0;
int alt_interface, interface_number;
int print_configuration(struct libusb_device_handle *hDevice, struct libusb_config_descriptor *config)
{
char *data;
int index;
data = (char *)malloc(512);
memset(data, 0, 512);
index = config->iConfiguration;
libusb_get_string_descriptor_ascii(hDevice, index, data, 512);
printf("\nInterface Descriptors: ");
printf("\n\tNumber of Interfaces: %d", config->bNumInterfaces);
printf("\n\tLength: %d", config->bLength);
printf("\n\tDesc_Type: %d", config->bDescriptorType);
printf("\n\tConfig_index: %d", config->iConfiguration);
printf("\n\tTotal length: %lu", config->wTotalLength);
printf("\n\tConfiguration Value: %d", config->bConfigurationValue);
printf("\n\tConfiguration Attributes: %d", config->bmAttributes);
printf("\n\tMaxPower(mA): %d\n", config->MaxPower);
free(data);
data = NULL;
return 0;
}
struct libusb_endpoint_descriptor* active_config(struct libusb_device *dev, struct libusb_device_handle *handle)
{
struct libusb_device_handle *hDevice_req;
struct libusb_config_descriptor *config;
struct libusb_endpoint_descriptor *endpoint;
int altsetting_index, interface_index=0, ret_active;
int i, ret_print;
hDevice_req = handle;
ret_active = libusb_get_active_config_descriptor(dev, &config);
ret_print = print_configuration(hDevice_req, config);
for (interface_index=0;interface_index<config->bNumInterfaces;interface_index++)
{
const struct libusb_interface *iface = &config->interface[interface_index];
for (altsetting_index=0; altsetting_index<iface->num_altsetting; altsetting_index++)
{
const struct libusb_interface_descriptor *altsetting = &iface->altsetting[altsetting_index];
int endpoint_index;
for(endpoint_index=0; endpoint_index<altsetting->bNumEndpoints; endpoint_index++)
{
const struct libusb_endpoint_desriptor *ep = &altsetting->endpoint[endpoint_index];
endpoint = ep;
alt_interface = altsetting->bAlternateSetting;
interface_number = altsetting->bInterfaceNumber;
}
printf("\nEndPoint Descriptors: ");
printf("\n\tSize of EndPoint Descriptor: %d", endpoint->bLength);
printf("\n\tType of Descriptor: %d", endpoint->bDescriptorType);
printf("\n\tEndpoint Address: 0x0%x", endpoint->bEndpointAddress);
printf("\n\tMaximum Packet Size: %x", endpoint->wMaxPacketSize);
printf("\n\tAttributes applied to Endpoint: %d", endpoint->bmAttributes);
printf("\n\tInterval for Polling for data Tranfer: %d\n", endpoint->bInterval);
}
}
libusb_free_config_descriptor(NULL);
return endpoint;
}
int main(void)
{
int r = 1;
struct libusb_device **devs;
struct libusb_device_handle *handle = NULL, *hDevice_expected = NULL;
struct libusb_device *dev, *dev_expected;
struct libusb_device_descriptor desc;
struct libusb_endpoint_descriptor *epdesc;
struct libusb_interface_descriptor *intdesc;
ssize_t cnt;
int e = 0, config2;
int i = 0, index;
char str1[64], str2[64];
char found = 0;
// Init libusb
r = libusb_init(NULL);
if(r < 0)
{
printf("\nFailed to initialise libusb\n");
return 1;
}
else
printf("\nInit successful!\n");
// Get a list of USB devices
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
{
printf("\nThere are no USB devices on the bus\n");
return -1;
}
printf("\nDevice count: %d\n-------------------------------\n", cnt);
while ((dev = devs[i++]) != NULL)
{
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
printf("Failed to get device descriptor\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
e = libusb_open(dev, &handle);
if (e < 0)
{
printf("Error opening device\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nDevice Descriptors: ");
printf("\n\tVendor ID: %x", desc.idVendor);
printf("\n\tProduct ID: %x", desc.idProduct);
printf("\n\tSerial Number: %x", desc.iSerialNumber);
printf("\n\tSize of Device Descriptor: %d", desc.bLength);
printf("\n\tType of Descriptor: %d", desc.bDescriptorType);
printf("\n\tUSB Specification Release Number: %d", desc.bcdUSB);
printf("\n\tDevice Release Number: %d", desc.bcdDevice);
printf("\n\tDevice Class: %d", desc.bDeviceClass);
printf("\n\tDevice Sub-Class: %d", desc.bDeviceSubClass);
printf("\n\tDevice Protocol: %d", desc.bDeviceProtocol);
printf("\n\tMax. Packet Size: %d", desc.bMaxPacketSize0);
printf("\n\tNumber of Configurations: %d\n", desc.bNumConfigurations);
e = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, (unsigned char*) str1, sizeof(str1));
if (e < 0)
{
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nManufactured: %s", str1);
e = libusb_get_string_descriptor_ascii(handle, desc.iProduct, (unsigned char*) str2, sizeof(str2));
if(e < 0)
{
libusb_free_device_list(devs, 1);
libusb_close(handle);
break;
}
printf("\nProduct: %s", str2);
printf("\n----------------------------------------");
if(desc.idVendor == 0xffff && desc.idProduct == 0x4)
{
found = 1;
break;
}
}//end of while
if(found == 0)
{
printf("\nDevice NOT found\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return 1;
}
else
{
printf("\nDevice found");
dev_expected = dev;
hDevice_expected = handle;
}
e = libusb_get_configuration(handle, &config2);
if(e!=0)
{
printf("\n***Error in libusb_get_configuration\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
printf("\nConfigured value: %d", config2);
if(config2 != 1)
{
libusb_set_configuration(handle, 1);
if(e!=0)
{
printf("Error in libusb_set_configuration\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
else
printf("\nDevice is in configured state!");
}
libusb_free_device_list(devs, 1);
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
}
e = libusb_claim_interface(handle, 0);
if(e < 0)
{
printf("\nCannot Claim Interface");
libusb_free_device_list(devs, 1);
libusb_close(handle);
return -1;
}
else
printf("\nClaimed Interface\n");
active_config(dev_expected, hDevice_expected);
// Communicate
char *my_string, *my_string1;
int transferred = 0;
int received = 0;
int length = 0;
my_string = (char *)malloc(nbytes + 1);
my_string1 = (char *)malloc(nbytes + 1);
memset(my_string, '\0', 64);
memset(my_string1, '\0', 64);
strcpy(my_string, "Prasad Divesd");
length = strlen(my_string);
printf("\nTo be sent: %s", my_string);
e = libusb_bulk_transfer(handle, BULK_EP_IN, my_string, length, &transferred, 0);
if(e == 0 && transferred == length)
{
printf("\nWrite successful!");
printf("\nSent %d bytes with string: %s\n", transferred, my_string);
}
else
printf("\nError in write! e = %d and transferred = %d\n", e, transferred);
sleep(3);
i = 0;
for(i = 0; i < length; i++)
{
e = libusb_bulk_transfer(handle, BULK_EP_OUT, my_string1, 64, &received, 0); //64: Max Packet Length
if(e == 0)
{
printf("\nReceived: ");
printf("%c", my_string1[i]); //Will read a string from LPC2148
sleep(1);
}
else
{
printf("\nError in read! e = %d and received = %d\n", e, received);
return -1;
}
}
e = libusb_release_interface(handle, 0);
libusb_close(handle);
libusb_exit(NULL);
printf("\n");
return 0;
}