I am trying to build and send 802.11 frames in C. I saw that it is possible to do it with pcap for instance. However, in all example I saw, I have to set myself sequence number and other control fields. So I'm wondering if there is an API that permits to manage all this control part and where I only have to specify addresses ?
Thank you in advance,
First of all what type of packet are you trying to make? Data frames or beacon frames.....
If you are creating from the scratch you need to set all the parameters yourself, i am using this header file
[ieee80211]http://lxr.free-electrons.com/source/include/linux/ieee80211.h
for the 802.11 configuration parameters, and for radiotap headers , you can use
[radiotap]http://lxr.free-electrons.com/source/include/net/ieee80211_radiotap.h
i can give you an example code(part of) of creating beacon frames
// Add the radiotap header
radiotap->it_version = 0;
radiotap->it_len = sizeof(*radiotap) + sizeof(dataRate);
radiotap->it_present = (1 << IEEE80211_RADIOTAP_RATE);
// Beacon packet flags
dot80211->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON;
dot80211->i_fc[1] = IEEE80211_FC1_DIR_NODS;
dot80211->i_dur[0] = 0x0;
dot80211->i_dur[1] = 0x0;
// Destination = broadcast (no retries)
memcpy( dot80211->i_addr1, mac_Destination, IEEE80211_ADDR_LEN );
// Source = our own mac address
memcpy( dot80211->i_addr2, mac_source, IEEE80211_ADDR_LEN );
// BSS = our mac address
memcpy( dot80211->i_addr3, mac_BSSID, IEEE80211_ADDR_LEN );
// Sequence control: Automatically set by the driver
beacon -> beacon_timestamp = TimeStamp;
printf("%"PRIu64,beacon -> beacon_timestamp);
// interval = 100 "time units" = 102.4 ms
// Each time unit is equal to 1024 us
beacon->beacon_interval = BEACON_INTERVAL;
// capabilities = sent by ESS
//beacon->beacon_capabilities = x0003;
For Example :
dot80211->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON;
You can the set the FCS(frame control) like this, which is defined in the header.
My suggestion is to create your own header files or modify it according to your need..
Hope this helps ??
Related
I am working on vector control of PMSM. I've got a problem with the dead-band module, and I don't understand what I'm actually doing wrong here. The register setting for EPWM modules 1 and 2 is given as follows:
For EPWM module 1 configuration
EPwm1Regs.TBPRD = PERIOD;// Period = TBCLK counts
EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM1A
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
EPwm1Regs.DBFED = DEAD_TIME; //
EPwm1Regs.DBRED = DEAD_TIME; //
For EPWM Module 2 Configuration
EPwm2Regs.TBPRD = PERIOD; // Period = 1600 TBCLK counts
EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM2A
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
EPwm2Regs.DBFED = DEAD_TIME; //
EPwm2Regs.DBRED = DEAD_TIME; //
I'm following an example (3.4) from the technical manual "sprug04a."
the compare values are initially initialized as
EPwm1Regs.CMPA.half.CMPA = 0; // adjust duty for output EPWM1A
EPwm2Regs.CMPA.half.CMPA = 0; // adjust duty for output EPWM2A
and compare values are updated in the code like:
EPwm1Regs.CMPA.half.CMPA = PERIOD - Sa;
EPwm2Regs.CMPA.half.CMPA = PERIOD - Sb;
where S_ab are the values obtained from modulation technique.
EPWM2 module is working well but EPWM1 isn't working. we are suppose to have EPWM1A complimentary signal across EPWM1B but EPWM1B shows same as EPWM1A. The scope is attached for better understanding. Need recommendation in this regards.EPWM1A&B EPWM2A&B reference, what should i need to check? as i checked technical manual and example codes but still i didnt get what i am doing wrong. Your suggestions will be valuable in this regards.
How to properly encode data with NanoPB when having several nested 'repeated' fields?
This is my schema:
message Report {
message SensorData {
required uint32 sensorid = 1;
required uint32 sample = 2;
}
message DeviceData {
required uint32 devid = 1;
repeated SensorData sensor_data = 2;
}
required uint32 reportnum = 1;
repeated DeviceData dev_data = 2;
}
I have already made a working version in which SensorData fields are embedded inside DeviceData message based on the server.c example from the NanoPB source. This way I have only one repeated field and everything works fine. However this way I have to repeat the 'devid' field for every sensorid and every 'sample', instead of giving it just one time and then loop through an array of SensorData messages. However I am struggling to encode this with NanoPB, the decoding part is in Python. Can someone give me an example how to properly encode data in this case?
For me the simplest way to do this was by statically defining the size of the array's using a nanopb options file. After that you can access each element just like an array.
report.dev_data[i].devid[j] = 1234;
report.dev_data[i].sensor_data[j] = 9876;
from the "Bluetooth Device Access Guide", I've read that the Bluetooth API should be accessable from C or from C++. I've found some C-headers (IOBluetoothUserLib.h, Bluetooth.h) in the IOBluetooth framework that are related to Bluetooth and contain enumerations and data structured to define search creteria but I fail to find any function that takes such enumeration or data structure as parameter. According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
Background: We use OS/X as a developing plattform for devlopment of BLE enabled microcontrollers. To update firmware on this microcontrollers I want to write a BLE bootloader and I want to have a commandline client to update the firmware. All of the code is written in C++ and I wouldn't like to learn objectiv-C for this small task.
Any pointers, documentation, examples?
thank you
Torsten
According to the documentation I would have to create a CBCentralManager but I fail to find a way to do so from C or C++.
The documentation you refer to is for classic Bluetooth, for which the IOBluetooth framework has some functionality. CBCentralManager is the manager from CoreBluetooth, which is for Bluetooth LE only.
For classic Bluetooth, the manager you want is the HID Manager from the IOKit framework, documentation for which can be found here. If you search around, you'll find lots of examples of C++ usage of IOKit and IOHIDManager (1, 2).
IOKit may in fact give you all the functionality you need, but IOBluetooth supplies some Bluetooth specific features. From Developing Bluetooth Applications:
Although you don’t need to use the Bluetooth API to access a HID-class device, you may choose to use functions or methods from the Bluetooth framework to enhance the user’s experience. For example, your application can provide Bluetooth-specific information that lets the user know if a device doesn’t support a particular service.
I agreed with Henrik you'll need some glue. Look at RedBearLab guys work and precise to class.
ofxBLE. h/mm
// C++ interface //
// (Obj-C may be a superset of C, but this just makes interopability
// easier with oF)
class ofxBLE {
protected:
ofxBLEDelegate *btDelegate;
public:
ofxBLE();
~ofxBLE();
void scanPeripherals();
void sendPosition(uint8_t x, uint8_t y);
bool isConnected();
};
...
- (void)bleDidDisconnect {
NSLog(#"->Disconnected");
}
- (void)bleDidReceiveData:(unsigned char *)data length:(int)length {
}
#end
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// C++ class implementation
ofxBLE::ofxBLE() {
btDelegate = [[ofxBLEDelegate alloc] init];
}
ofxBLE::~ofxBLE() {
}
void ofxBLE::scanPeripherals(){
[btDelegate scanForPeripherals];
}
void ofxBLE::sendPosition(uint8_t x, uint8_t y) {
// position should be NORMALIZED to between 0 and 255 BEFORE
// passing into this method!
[btDelegate sendPositionX:x withY:y];
}
I am new to DirectShow. I, like many others, am trying to create a socket-based P2P streaming solution for a WPF-based card game. I want each player to be able to see each other via small video windows.
My questions are two-fold. The first is How do I lower the frame sample rate and resolution? I believe 320x200 x 15 to 20 fps should be fine. I am using the SampleGrabber callback to grab frame data and send it over the socket; which is actually working with no compression at 640x480 resolution.
My second question is, since each frame contains 921,600 bytes, this really bogs down and I get very slow rendering just across my local WiFi connected LAN. I added a simple MJPEG compression (wanting to switch to h.264 later) and I noticed the bytes drop to around 330-360k. Not a bad improvement.
On the receiving end Do I need to create a custom DirectShow Source Pin in order to serve up the bytes received from the socket so I can attach a decoder and render the bytes in a window?
I just wanted to ask this first since it seems like a lot of work to create a new COM object (haven't done that in about 15 years!), register it, and use/debug it.
Is there perhaps another way?
Also if that is the way to go, should I use a SampleGrabber on the receiving end and create a BitmapSource from the decompressed bytes, or should I allow DirectShow to create a child window? Thing is, I want to have more than one other player and I set an extra byte in the socket to tell what table position they are in. How do I render each position in turn?
For those that are interested, here is how you set the resolution and add an encoder/compressor:
// Create a graph builder
int hr = captureGraphBuilder.SetFiltergraph(graphBuilder);
// Find a capture device (WebCam) and attach it to the graph
sourceFilter = FindCaptureDevice();
hr = graphBuilder.AddFilter(sourceFilter, "Video Capture");
// Get the source output Pin
IPin sourcePin = DsFindPin.ByDirection((IBaseFilter)sourceFilter, PinDirection.Output, 0);
IAMStreamConfig sc = (IAMStreamConfig)sourcePin;
int count;
int size;
sc.GetNumberOfCapabilities(out count, out size);
VideoInfoHeader v;
AMMediaType media2 = null;
IntPtr memPtr = Marshal.AllocCoTaskMem(size);
for (int i = 0; i < count; ++i)
{
sc.GetStreamCaps(i, out media2, memPtr);
v = (VideoInfoHeader)Marshal.PtrToStructure(media2.formatPtr, typeof(VideoInfoHeader));
// Break when width is 160
if (v.BmiHeader.Width == 160)
break;
}
// Set the new media format t0 160 x 120
hr = sc.SetFormat(media2);
Marshal.FreeCoTaskMem(memPtr);
DsUtils.FreeAMMediaType(media2);
// Create a FramGrabber
IBaseFilter grabberF = (IBaseFilter)new SampleGrabber();
ISampleGrabber grabber = (ISampleGrabber)grabberF;
// Set the media type
var media = new AMMediaType
{
majorType = MediaType.Video,
subType = MediaSubType.MJPG
//subType = MediaSubType.RGB24
};
// The media sub type will be MJPG
hr = grabber.SetMediaType(media);
DsUtils.FreeAMMediaType(media);
hr = grabber.SetCallback(this, 1);
hr = graphBuilder.AddFilter(grabberF, "Sample Grabber");
IPin grabberPin = DsFindPin.ByDirection(grabberF, PinDirection.Input, 0);
// Get the MPEG compressor
Guid iid = typeof(IBaseFilter).GUID;
object compressor = null;
foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory))//.MediaEncoderCategory))
{
if (device.Name == "MJPEG Compressor")
{
device.Mon.BindToObject(null, null, ref iid, out compressor);
hr = graphBuilder.AddFilter((IBaseFilter)compressor, "Compressor");
break;
}
string name = device.Name;
}
// This also works!
//IBaseFilter enc = (IBaseFilter)new MJPGEnc();
//graphBuilder.AddFilter(enc, "MJPEG Encoder");
// Get the input and out pins of the compressor
IBaseFilter enc = (IBaseFilter)compressor;
IPin encPinIn = DsFindPin.ByDirection(enc, PinDirection.Input, 0);
IPin encPinOut = DsFindPin.ByDirection(enc, PinDirection.Output, 0);
// Attach the pins: source to input, output to grabber
hr = graphBuilder.Connect(sourcePin, encPinIn);
hr = graphBuilder.Connect(encPinOut, grabberPin);
// Free the pin resources
Marshal.ReleaseComObject(sourcePin);
Marshal.ReleaseComObject(enc);
Marshal.ReleaseComObject(encPinIn);
Marshal.ReleaseComObject(encPinOut);
Marshal.ReleaseComObject(grabberPin);
// Create a render stream
hr = captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, grabberF);
Marshal.ReleaseComObject(sourceFilter);
Configure(grabber);
I want to re-project an HDF from UTM(WGS84) to sinusoidal(WGS84), so I try to use GDALAutoCreateWarpedVRT to finished it. The code is below:
hSrcDS = (GDALDataset*)GDALOpen("HJ1ACCD1.hdf", GA_ReadOnly);
const char *pszSrcWKT = NULL;
char* pszDstWKT = NULL;
//pszSrcWKT = ProjectionStr;
pszSrcWKT=GDALGetProjectionRef(hSrcDS);
CPLAssert( pszSrcWKT != NULL &&strlen(pszSrcWKT) > 0 );
OGRSpatialReference oSRS;
oSRS.SetSinusoidal(0,0,0);
oSRS.SetWellKnownGeogCS("WGS84");
oSRS.exportToWkt(&pszDstWKT );
GDALWarpOptions*psWarpOptions = GDALCreateWarpOptions();
psWarpOptions->dfWarpMemoryLimit=500*1024*1024;
hDstDS=(GDALDataset*)(GDALDataset*)GDALAutoCreateWarpedVRT(hSrcDS,pszSrcWKT,pszDstWKT,GRA_Bilinear ,20,psWarpOptions);
GDALDriver *poDriverTiff;
poDriverTiff=GetGDALDriverManager()->GetDriverByName("GTIFF");
poDriverTiff->CreateCopy("d:\\toto.tif",(GDALDataset*)hDstDS,false,NULL,NULL,NULL);
When I set oSRS.SetSinusoidal(0,0,0),the result seems good, but the resolution is doubled (from 30 to 60). It's so weird.
According to the API docs for GDALAutoCreateWarpedVRT:
The GDALSuggestedWarpOutput() function is used to determine the bounds and resolution of the output virtual file which should be large enough to include all the input image
There is also a GDALSuggestedWarpOutput2() function to help suggest output file size for a similar set of requirements.