1

I have a small c program which connect and authenticate with my security DVR which in turn starts sending me data over the socket. I can connect on port 5000 or port 80 sending different authentification methods to start receiving the video/images. My problem is; I am new to c first of all, and I am very lost on how to process the data received over the socket. This is the data I am sending to authenticate.

char authenticate[] = {
    0x31, 0x31, 0x31, 0x31, 0x88, 0x00, 0x00, 0x00, 
    0x01, 0x01, 0x00, 0x00, 0x88, 0x7d, 0xa6, 0x47, 
    0x0c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x61, 0x64, 0x6d, 0x69, 0x6e, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x34, 
    0x35, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x43, 0x6f, 0x6c, 0x74, 0x6f, 0x6e, 0x73, 0x2d, 
    0x4d, 0x61, 0x63, 0x42, 0x6f, 0x6f, 0x6b, 0x2d, 
    0x50, 0x72, 0x6f, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 
    0x6c, 0x00, 0x00, 0x00, 0x35, 0x34, 0x32, 0x36, 
    0x39, 0x36, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 
 };

  x = sendto(sockfd, authenticate, sizeof(authenticate), 0,
  (struct sockaddr*)&servaddr, sizeof(servaddr));

I am then recieving the data with

while(1)
{
  n = recvfrom(sockfd, data, 2048, 0, NULL, NULL);

When I connect via http port 80 This is the image data that I receive:

Content-length: 2153
Content-type: image/jpeg

ˇÿˇ‡JFIFHHˇ€Cˇ€Cˇ¿#ˇƒ  
    ˇƒ8 2A!$X"#3QRTqëîóò“’÷ˇƒˇƒ@   
        !1A"2QRqrë#SacŰ¢≥—“ÒBCstÇí¥”ˇ⁄     ?e›n◊}mÀ⁄ÔÅ≥j¿ò[0ÂáֱNU…9'*‚®@ô &yéïùr‰Ù®{ï“däŒÆl$Kkë       R,√fƒSl—EX
    z   \û£≠âflüÈ‚≠ê*àÉ*—1E;q}Ìp6@>øÆÂòŸR≠^Ì˝çò ı;R∆b¡»ü>aÊ∫a˙5KKüz∑¶Î´D“≤κl∂ÎÓ„∆Àn∫¥•sh8vß4≠äöûñy‰H¢çyºí0TQrÏ@π dÅèåfi*XY*F¨Óƒl™¢‰˝S^sgh]î…flzXNü‡†2∑ñæ5t€Tp`qìåos◊iGùjˆ˙+FÈ™‚‘_§≈[”Jˇ     *•<*´∆≥ÁpVGfl
    ï¶ñ—€{ñgíJmd*ôï„å[YT-J†∞π∂¯ë…{¶dyÓaÓhå©!øg⁄∆™≤È:
    ≥Ô`Mú)∞ÚÌǯhˇÿ„Tø∑,9˛õ°˛ıØö~ø«ûÔ˝˙aa{ÜÔû÷Èé‡ÂΩk÷ºµ\sÉÒ¬XÓ∞`¯⁄X“">eäÅœ»G¡ìöÜ"˘mütòÅtuÓbÌh;vB1dflL ∂)
    ´È
    Hm∂Í
    Ω¡î*Ä≤e‘nÄï‘HΩ…77ÙIè6%â%ãµ"T¿n¢Í3%‹zj#™:”ÂmR˛=L  ZsZ[_ïz±»r…™2®ú.«]∑$q¢1)ùftÙ˘îà[q£°Îü&%Ï÷@á∂¿ôEy!ËÇJ0‚‚j»¥|∆fi–ü5"èRj›D˘„õUäú≥û>•«bdôãq]Ö$2ˆ„Gc#,ó±Ò<√-p}ZÍSÛ                                                          £ëóŒsäóNçı≠◊òÊö•mÈÇ_W„Y2∆∫9œxπŸ¸*±’dË⁄1(¸05{üfW∆Éû
    ‘ÿSÑ‘„û.JTÓ9˙Ìø˝∆º=∆        ¬ï∆h≥!`uˆ’Uçõèd„Ï…ı®*GÕıŸ6iíÆiñ¶’ØmBë‰WáÈö˛â‚ı∞>Ó˛◊_Â’ˇπ?º”˘øh~8TÔÕ/ùˆO¬Ewü^◊]…6
    ÕïÊ«p2ˆ◊ä”õU÷ËÖˆ◊䲲ãk–«_2ûk4Éÿ‰aÖƒîP∑ùg⁄†·¢µ’ÂS÷}XNï¯5GWæßGk”óS8fòˇ;˝âp;≈“ƒ5ˇ˜„Éû·&Áa¨ö2tÿ±íÉìcÇeÓ"¬Â„(8¯:øØíM    £rmfiá~≠æ(:oT/U≤/täó       U√ñT0ëªÕ      ê’¢víRT@˙‚ìO7ÖÆÒ‘D<dm@;F®—yÑmPǃ5É+FZÀ"8≥-˙7"ç–ãm{Å∑Öunü»à·®icëcoDìf¬·ñ)!å A¡ñÂNrx√aeP\ZM®£      ‘Y\<kJÿ‚’Ó#„Œª+â3
    ¨π©%Uü±Àñ¨œò§S2àŸßUJjwûYãZ@Ç∆˚¶&hr⁄xj¬ì  È™sàK-…  28Fm‡Ôr√û      8Qè
    ª∑ØP ptt£‚N—Œ∆Iπ ıo«Y{Èe.U[´‰•ı∫ÎæöÙU’‘…)¶Gy
    †“ä]ãä6U≤Å∞b 7X„        ™˙@ÓMÖ∑>_ó
    =fiÔ>·π∂ˇ÷ãÎΩfl«Y!µÎô≥—ß;¨J™èΩ|tLoîRˇM›.@nŸÍ±≈±Ê∏Ï~qkãsv≈Xõ‰í∞Lπ/cR,j*6.Sí„ÿ˘fÑ»7f|_™≥RçÿíE°°bã {{Ïõç#·Ãæ:7çú√´u      o
    ⁄N¨Ω\€ù◊K,Z4àÕ8N\˙πÍë’D∫vbfl∏¢>äz.¸¨⁄Ä‘°dx≈ªàˆÕ45‡ßõub-ü%TVTN8⁄∞¨≤µÁñÜD[;o—˘ƒNˇóóØ[ò;´¡O*∫¿ƒ©∏2ߘG#20˘H∆µªú’2€∂O°Â⁄Ùb®äÌ/hÿQÁXÓŸJzB¬Öw]Ù2ÿ—⁄§∆«gÜö·´˚Ëãt‚+˛Iì¯∂⁄nÎ{ºVʬ)aà∆´°ÀÚËÃkr÷â„ç^1©ôæ
    óv'ô8∆ãπkB˙цπ¯zÉsÀpv;Ã]ÓI€[Ìj/˙A≤øÒ}O˚ËS|Dûƒˇ¶3=ÓÍæ6?Ú…å!¥›¨Ûˆ¸f…€·I~à≥      g>∆®‰√Û0≥30®Æ) èMÖçGÃ∑dÑÖ∞¥Œéf≥ÔyµE¢Yå.õ·ç+r˙ú ≤ZÄP    ‰y¨Km⁄±~ävfl¡'I+b»Ñî[ö<¬        æñ8raEãk

I am unsure if this data is some weird encoding or if it need to be processed somehow to make it valid. I have searched around with no luck or examples of how to properly do this. If i connect via the data port (port 5000 which sends via instead of an image) the data looks pretty much the same although i know it may be processed or unprocessed H.246 video data.

csechols
  • 51
  • 4
  • is this only via port 80? what happens if you connect from a non-reserved port ( say 5055 )? Also show us how are you processing the array `data` on the receiver's side – sukhvir Oct 20 '13 at 23:42
  • looks like you try to visualize binary data as characters... could you share your output-method? – xmoex Oct 20 '13 at 23:48
  • The only other port available is 5000 which is used for sending video to the client. When I use port 5000 it sends me info regarding the each camera setting and then the video data which looks pretty much the same as the image data above. I do not have access to the server side code which is another one of the problems. – csechols Oct 20 '13 at 23:50
  • I am outputting with fwrite(data, 1, n, stdout) – csechols Oct 20 '13 at 23:57
  • That looks like 1 frame of an image. You're receiving a jpeg image. What you need to do is read the header which prints the content-length and type.. It doesn't seem chunked so after reading the header, read content-length bytes and parse that as a jpeg.. Save it to disk or do w/e with it.. If it was bmp, it'd be much easier than using jpeg. – Brandon Oct 21 '13 at 00:04
  • So that raw data should be sufficient to create and image ? – csechols Oct 21 '13 at 00:21

2 Answers2

0

The raw data is an image. It starts after the blank line which terminate the headers.

Code:

n = recvfrom(sockfd, data, 2048, 0, NULL, NULL); // might as well replace with read().  
// use a much larger buffer, ideally large enough to fit largest possible whole image

headers_end_str = "\r\n\r\n";
headers_end_position = strstr(data, headers_end_str);
headers_end_position += strlen(headers_end_str );

if (headers_end_position > n) { ... } // handle errors

FILE* fh = fopen("image.jpg", "wb");

int result = fwrite( &( data[ headers_end_position ), n - headers_end_position, 1, fh);
// check result for errors

// continue reading from socket and writing to file, subsequent reads do not have headers

This should get you started, you need to fine tune reading additional data, and also error handling and end of file.

However, even before you have done all that, you should be able to run "file -s image.jpg" (on linux, or cygwin) and it will tell you it's a JPEG image.

Alex I
  • 19,689
  • 9
  • 86
  • 158
0

I used WireShark to monitor the communication between the DVR and it's web browser plugin client and the authentication message header is similar to your post (0x31 0x31 0x31 0x31...). How did you construct this array? I searched a lot for this protocol documentation but I didn't find.

In my case I do the requests at port 7171 (it's a DVR settings). I also used a while(true) to keep listening this port and the server sends me a h264 stream.

The problem is that the stream is not like rtps protocol describes, see this great post. In our case we have to parse a kind of proprietary header first (that starts with 0x31 0x31 0x31 0x31) to stract the frame, sps and pps.

Community
  • 1
  • 1
Elmo
  • 19
  • 1
  • 6