I am using SharpPCap which is built on WinPCap to capture UDP traffic. My end goal is to capture the audio data from H.323 and save those phone conversations as WAV files. But first thing is first - I need to figure out what my UDP packets are crossing the NIC.
SharpPCap provides a UdpPacket class that gives me access to the PayloadData of the message. But I am unsure what do with this data. It's a Byte[] array and I don't know how to go about determining if it's an RTP or RTCP packet.
I've Googled this topic but there isn't much out there. Any help is appreciated.
Look at the definitions for RTP and RTCP packets in RFC 3550:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I won't reproduce the legend for all of the above - it's quite long - but take a look at Section 5.1.
With that in hand you'll see there's not a lot you can do to determine if a packet contains RTP/RTCP. Best of all would be to sniff, as other posters have suggested, the media stream negotiation. Second best would be some sort've pattern matching over a sequence of packets: the first two bits will be 10, followed by the next two bits being constant, followed by bits 9 through 15 being constant, then 16 -> 31 incrementing, and so on.
I would look at the packet detectors in Wireshark, which can decode most common protocols available.
If communucations are done over RTSP, take a look at the udp port that is negotiated upon SETUP.
the udp port will tell you if it is RTP or RTCP (also worth noting that RTP is usually done over even port numbers and RTCP on odd).
finally if you are communicating via RTSP you can take the list of payload numbers from the SDP file from the DESCRIBE and then check the payload type in the RTP header to tell the codec you need to decode the payload.
I believe you need to look at the SIP packets that come before the RTP packets.
There is a discussion on this issue on Pcap.Net site.
Related
I use WMI to get Printers and PrintJobs.
for each PrintJob, there's a property name "StatusMask". I'm trying to use this to monitor PrintJob's status.
I did a little test, found that when printing, it's 8272, when out of paper, it's 8274.
my question is, where I can get information of what these codes meaning? and how to use it?
I've already googled 'C# printjob statusmask', no valuable information.
According to MSDN, it is the following:
Bitmap of the possible statuses that relate to this print job.
1 (0x1)
Paused
2 (0x2)
Error
4 (0x4)
Deleting
8 (0x8)
Spooling
16 (0x10)
Printing
32 (0x20)
Offline
64 (0x40)
Paperout
128 (0x80)
Printed
256 (0x100)
Deleted
512 (0x200)
Blocked_DevQ
1024 (0x400)
User_Intervention_Req
2048 (0x800)
Restart
Hey programming community. So I'm using TagLib Sharp library to fetch the metadata from my .mp3s. Everything is going great with one exception. I can read the rating from my MP3s of they're whole numbers (set my Musicbee). Meaning
Stars
5 = 255
4 = 196
3 = 128
2 = 64
1 = 1
unrated=0
The problem I am running into is I use MusicBee where I can set half star ratings. So the value that I should be getting from my ratings is:
Stars
5 = 255
4.5 = 224
4 = 196
3.5 = 160
3 = 128
2.5 = 96
2 = 64
1.5 = 48
1 = 1
unrated=0
However, this is what TagLib is reading:
5 = 255
4.5 = 0
4 = 196
3.5 = 0
3 = 128
2.5 = 0
2 = 64
1.5 = 0
1 = 1
This is the code that I am using to get the ratings:
TagLib.File file = TagLib.File.Create(fi.FullName);
TagLib.Tag tag = file.GetTag(TagLib.TagTypes.Id3v2);
TagLib.Id3v2.PopularimeterFrame tagInfo = TagLib.Id3v2.PopularimeterFrame.Get((TagLib.Id3v2.Tag)tag, "Windows Media Player 9 Series", true);
byte rate = tagInfo.Rating;
//This is where I'm storing the value as a string to process it later
id3.Rating = tagInfo.Rating.ToString();
My question is, well, two-fold. Is there another usr that I should/could use instead of "Windows Media Player 9 Series"? OR is there a better way that I should be getting the rating from my mp3s? Should I abandon the half-star ratings of Musicbee?
Also, is there a "help" file on taglib? It seems like EVERYTHING that I can find on it is found here. I don't even know what I'm setting to "true" in my code above.
Thank you for your help in advance!
* Update *
This is not an answer just fixing a typo from:
1 = 24 to
1 = 1
According to the ID3v2(3) specification, the purpose of the frame 4.18 POPM
... is to specify how good an audio file is. Many interesting applications could be found to this frame such as a playlist that features better audiofiles more often than others or it could be used to profile a person's taste and find other 'good' files by comparing people's profiles. The frame is very simple. It contains the email address to the user, one rating byte and a four byte play counter, intended to be increased with one for every time the file is played. The email is a terminated string. The rating is 1-255 where 1 is worst and 255 is best. 0 is unknown. If no personal counter is wanted it may be omitted.
I know that programs like MediaMonkey use this half star ratings, but they are not fully compatible with the specification. The linked MediaMonkey forum thread explains, how they calculate the half stars.
You can also have a look for "RATING MM" in the documentation from Mp3tag. It tells about the various implementations of ratings: http://help.mp3tag.de/main_tags.html
This KODI thread shows how they calculate it:
Values Rating
-----------------------
0 0 0
0.5 2-22 1
1 1, 23-31 2
1.5 32-63 3
2 64-95 4
2.5 96-127 5
3 128-159 6
3.5 160-195 7
4 196-223 8
4.5 224-254 9
5 255 10
When using TagLibSharp, the 2nd argument of TagLib.Id3v2.PopularimeterFrame.Get should be the value of the "Email to user" field of the POPM frame.
This value should be "MusicBee" in your case, and not "Windows Media Player 9 Series".
=> The working code is as follows (tested with real-life MusicBee file)
TagLib.File file = TagLib.File.Create(fi.FullName);
TagLib.Tag tag = file.GetTag(TagLib.TagTypes.Id3v2);
TagLib.Id3v2.PopularimeterFrame tagInfo = TagLib.Id3v2.PopularimeterFrame.Get((TagLib.Id3v2.Tag)tag, "MusicBee", true);
byte rate = tagInfo.Rating;
NB : MusicBee stores "half-stars" with a slightly different convention than the one you imagined : 54 = 1,5 - 118 = 2,5...
Part one of my question is even if this is possible? I will briefly describe my situation first.
My work has a licence for a software that performs a very specific task, however most of our time is spent exporting data from the results into excel etc to perform further analysis. I was wondering if it was possible to dump all of the data into a C# object so that I can then write my own analysis code, which would save us a lot of time.
The software we licence was written in Fortran, but we have no access to the source code. The file looks like it is written out in binary, however I do not know if it is unformatted / sequential etc (is there anyway to discern this?).
I have used some of the other answers on this site to successfully read in the data to a byte[], however this is as far as I have got. I have tried to change portions to doubles (which I assume most of the data is) but the numbers do not strike me as being meaningful (most appear too large or too small).
I have the documentation for the software and I can see that most of the internal variable names are 8 character strings, would this be saved with the data? If not I think it would be almost impossible to match all the data to its corresponding variable. I imagine most of the data will be double arrays of the same length (the number of time points), however there will also be some arrays with a longer length as some data would have been interpolated where shorter time steps were needed for convergence.
Any tips or hints would be appreciated, or even if someone tells me its just not possible so I don't waste any more time trying to solve this.
Thank you.
If it was formatted, you should be able to read it with a text editor: The numbers are written in plain text.
So yes, it's probably unformatted.
There are different methods still. The file can have a fixed record length, or it might have a variable one.
But it seems to me that the first 4 bytes represent an integer containing the length of that record in bytes. For example, here I've written the numbers 1 to 10, and then 11 to 30 into an unformatted file, and the file looks like this:
40 1 2 3 4 5 6 7 8 9 10 40
80 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 80
(I added the new line) In here, the first 4 bytes represent the number 40, followed by 10 4-byte blocks representing the numbers 1-10, followed by another 40. The next record starts with an 80, and 20 4-byte blocks containing the numbers 11 through 30, followed by another 80.
So that might be a pattern you could try to see. Read the first 4 bytes and convert them to integer, then read that many bytes and convert them to whatever you think it should be (4 byte float, 8 byte float, et cetera), and then check whether the next 4 bytes again represents the number that you read first.
But there other methods to write data in Fortran that doesn't seem to have this behaviour, for example direct access and stream. So no guarantees.
I'm sort of new at this and I'm writing a small application to read data from a voltmeter. It's a RadioShack Digital Multimeter 46-range. The purpose of my program is to perform something automatically when it detects a certain voltage. I'm using C# and I'm already familiar with the SerialPort class.
My program runs and reads the data in from the voltmeter. However, the data is all unformatted/gibberish. The device does come with its own software that displays the voltage on the PC, however this doesn't help me since I need to grab the voltage from my own program. I just can't figure out how to translate this data into something useful.
For reference, I'm using the SerialPort.Read() method:
byte[] voltage = new byte[100];
_serialPort.Read(voltage, 0, 99);
It grabs the data and displays it as so:
16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 3
0 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6
198 30 6 126 254 30 0 30 24 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 254 30 6
126 252 30 0 6 0 30 0 254 30 6 126 254 30 0
The space separates each element of the array. If I use a char[] array instead of byte[], I get complete gibberish:
▲ ? ? ▲ ♠ ~ ? ▲ ♠ ▲ ? ? ▲ ♠ ~ ? ▲ ♠ ▲ ? ? ▲ ♠ ~ ? ▲ ♠
Using the .ReadExisting() method gives me:
▲ ?~?♠~?▲ ▲? ▲ ?~♠~?▲ ?↑ ▲ ??~♠~?▲ F? ▲ ??~♠~?▲ D? ▲ ??~♠~?▲ f?
.ReadLine() times out, so doesn't work. ReadByte() and ReadChar() just give me numbers similar to the Read() into array function.
I'm in way over my head as I've never done something like this, not really sure where else to turn.
It sounds like you're close, but you need to figure out the correct Encoding to use.
To get a string from an array of bytes, you need to know the Code Page being used. If it's not covered in the manual, and you can't find it via a google/bing/other search, then you will need to use trial and error.
To see how to use GetChars() to get a string from a byte array, see Decoder.GetChars Method
In the code sample, look at this line:
Decoder uniDecoder = Encoding.Unicode.GetDecoder();
That line is specifically stating that you are to use the Unicode code page to get the correct code page.
From there, you can use an override of the Encoding class to specify different Code Pages. This is documented here: Encoding Class
If the Encoding being used isn't one of the standards, you can use the Encoding(Int32) override in the Constructor of the Encoding class. A list of valid Code Page IDs can be found at Code Pages Supported by Windows
There are two district strategies for solving your communications problem.
Locate and refer to appropriate documentation and design\modify a program to implement the specification.
The following may be appropriate, but are not guaranteed to describe the particular model DVM that you have. Nonetheless, they MAY serve as a starting point.
note that the authors of these documents comment that the Respective models may be 'visually identical', but also comments that '"Open-source packages that reportedly worked on LINUX with earlier RS-232 models do not work with the 2200039"
http://forums.parallax.com/attachment.php?attachmentid=88160&d=1325568007
http://sigrok.org/wiki/RadioShack_22-812
http://code.google.com/p/rs22812/
Try to reverse engineer the protocol. if you can read the data in a loop and collect the results, a good approach to reverse engineering a protocol, is to apply various representative signals to the DVM. You can use a short-circuit resistance measurements, various stable voltage measurements, etc.
The technique I suggest is most valuable is to use an automated variable signal generator. In this way, by analyzing the patterns of the data, you should be more readily be able to identify which points represent the raw data and which points represent stable descriptive data, like the unit of measurements, mode of operation, etc.
Some digital multimeters use 7 bit data transfer. You should set serial communication port to 7 data bits instead of standard 8 data bits.
I modified and merged a couple of older open source C programs together on linux in order to read the data values from the radio shack meter whose part number is 2200039. This is over usb. I really only added a C or an F on one range. My program is here, and it has the links where I got the other two programs in it.
I know this example is not in C#, but it does provide the format info you need. Think of it is as the API documentation written in C, you just have to translate it into C# yourself.
The protocol runs at 4800 baud, and 8N1 appears to work.
I am working with a BGP table of the Internet (a huge file). However, route summarization can be a problem. My main issue is that, sometimes, big chunks of IPv4 space are announced (i.e., 172.16.0.0/16), but also more specific and smaller routes are announced too (i.e., 172.16.64.0/18). So there are two redundant entries in the BGP table.
I would like to figure out a way to end up with a list of non-redundant IP addresses, just the big chunks. I am thinking of maybe comparing all of them and storing them in a list. Is there a method in C# to know if an IP address is part of a broader IP address? As in:
172.16.64.0/18 is part of 172.16.0.0/16 //true
Thanks a lot for all your help!
alemangui
Use simple math.
IP address is 4 bytes, iow a 32-bit integer. The subnet mask is exactly the same.
Given this, you can use an arithmetic AND to determine whether it is inside or outside the defined network.
EG:
IP: 192.168.0.1 = C0 . A8 . 00 . 01
Subnet: 192.168.0.0 = C0 . A8 . 00 . 00
Is in subnet?
Thus 0xC0A80001 & 0xC0A80000 == 0xC0A80000 => true
To answer the question of whether one net work exists in another, you can use the same approach, but right shift both numbers with the size of the 'largest' subnet.
EG:
Net A: 172.16.64.0/18 -> AC 10 40 00
Net B: 172.16.0.0/16 -> AC 10 00 00
Thus right shift both with 16 and apply previous op.
AC 10 & AC 10 == AC 10 -> true
Consider the bit patterns:
172.16.64.0
10101100.00010000.01000000.00000000
172.16.0.0
10101100.00010000.00000000.00000000
Note that the set bits in the more-specific address are the set bits in the more-general address, plus some more. So if we perform a bitwise AND on the two addresses, the result will be equal to the more-general.
Is this always a correct test? Well, if we have two addresses that do not have a containment relationship, ANDing the bits will clearly give a result which has at least one bit different from the proposed parent, so this is the test we want.
If you know which of your two addresses is the proposed parent, and which is the proposed child, then we can simply AND the bits and compare to the proposed parent. If they could be in either order, AND them and compare to both inputs separately.
To get at the actual bits, if you already have an IPAddress, use GetAddressBytes to get a byte[], use BitConverter to get a unit, then just use & for the bitwise AND.