Thông báo

Collapse
No announcement yet.

Giao thức TCP/IP và Web server với AVR

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • dhp11591
    replied
    Tks thầy ạ.
    Em đã đập hẳn code cũ đi, h đang viết lại, hy vọng chữa được hết những bệnh của cái code cũ.
    Hix, nhà bị cắt mạng, 24h mới onl đc 1 lần.

    Leave a comment:


  • nttam79
    replied
    Trả lời luôn được ko:
    Đặt đoạn code trong 2 cái tag \[CODE\] và \[/CODE\]. (Bỏ dấu \ đi nhé)
    Hiện tượng chạy mỗi lần ra mỗi kết quả thì coi lại cách khởi tạo giá trị các biến (biến input), có thể do không xóa hết giá trị cũ của vùng nhớ khi khởi tạo biến.

    Leave a comment:


  • dhp11591
    replied
    Anh ơi, anh xem giúp em code MD5 được không ạ? Triệu chứng của nó là chạy trên các máy khác nhau cho ra kết quả khác nhau và chạy trên cùng 1 máy cũng cho 2 kết quả khác nhau @@

    Code:
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define sbit(byte,bit) byte |= 1<<bit
    #define cbit(byte,bit) byte &= ~(1<bit)
    
    //Mang chua cac hang so se duoc xu ly trong 1 tac vu
    unsigned long k[64];
    //Khoi tao chuoi
    unsigned long h0 = 0x67452301;
    unsigned long h1 = 0xEFCDAB89;
    unsigned long h2 = 0x98BADCFE;
    unsigned long h3 = 0x10325476;
    //Xac dinh cac gia tri dich chuyen cua moi tac vu
    unsigned long r[64] = {7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22,
                                5,9,14,20, 5,9,14,20, 5,9,14,20, 5,9,14,20,
                                4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23,
                                6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21};
    
    void md5(unsigned long input[])
    {
         unsigned long *w;
         unsigned long f, g;
         //-------------------------------------------------------------------------
         //-------------------------------------------------------------------------
         //-----------------------BAT DAU VOOC CHUOI--------------------------------
         //Bat dau vong lap
         unsigned int n = 0, i = 0;
         while(n < 8)
         {
               w = &input[n];
               //Khoi tao bien
               unsigned long a = h0;
               unsigned long b = h1;
               unsigned long c = h2;
               unsigned long d = h3;
               unsigned long temp;
               for(i = 0; i < 64; i++)
               {
                     if(0 <= i <= 15)
                     {
                          f = (b & c) || ((~b) & d);
                          g = i;
                     }
                     else if(16 <= i <= 31)
                     {
                          f = (d & b) || ((~d) & c);
                          g = (5*i + 1) % 16;
                     }
                     else if(32 <= i <= 47)
                     {
                          f = b ^ c ^ d;
                          g = (3*i + 5) & 16;
                     }
                     else if(48 <= i <= 63)
                     {
                          f = c ^ (b || (~d));
                          g = (7*i) & 16;
                     }
                     temp = d;
                     d = c;
                     c = b;
                     b += (a + f + k[i] + w[g])<<r[i];
                     a = temp;
               }
               n += 8;
               h0 += a;
               h1 += b;
               h2 += c;
               h3 += d;
         }
         w = &input[0];
         w[0] = h0;
         w[1] = h1;
         w[2] = h2;
         w[3] = h3;
         printf("\n Ket qua hash = %x%x%x%x", h3, h2, h1, h0);
    }
    
    int main()
    {
        unsigned char input[129] = {""};
        //Tien xu ly
        unsigned int i = 0, n = 0;
        int j = 0;
        unsigned int bit_length = 8*strlen(input);
        unsigned int len = strlen(input);
        n = len + 1;
        sbit(input[len],7);
        if((bit_length % 512) < 448)
        {
                       i = 448 - bit_length - 8;
                       while(i)
                       {
                              j = 7;
                              while(j >= 0)
                              {
                                      cbit(input[n],j);
                                      j--;
                                      i--;
                              }
                              n++;
                       }
                       input[62] = bit_length / 256;
                       input[63] = bit_length % 256;
        }
        else
        {
                       n++;
                       while(n < 120)
                               input[n++] = 0;
                       input[126] = bit_length / 256;
                       input[127] = bit_length % 256;
        }
        //Khoi tao mang hang so
        for(i = 0; i < 64; i++)
               k[i] = abs(pow(2,32)*sin(i+1));
        //printf("\n Nhap chuoi dau vao:\n");
        //getc(input);
        md5((unsigned long)input);
        getch();
        return 0;
    }
    Em cảm ơn anh nhiều nhiều
    Ủa, mà sao post đựoc code trong khung như thầy Tâm vậy anh?
    Last edited by dhp11591; 30-08-2012, 16:21.

    Leave a comment:


  • sang84119
    replied
    Chào Thầy,
    Em đang làm project về TCP/IP trên arm cortex m3 stm32f107, không biết Thầy có làm qua chưa? có nhìu ví dụ mẫu vễ webserver on chip quá, nhưng ko có ví dụ nào về webserver chạy trên PC hết, nên em gặp rất nhìu khó khăn ( nhìu lắm, ko biết phải hỏi sao luôn đó Thầy)... ko biết thầy có tài liệu gì không, cho em tham khảo với.
    Cảm ơn Thầy.

    Leave a comment:


  • dhp11591
    replied
    Vâng, em cảm ơn thầy ạ.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Hi, tự nhiên làm phiền thầy mà còn chưa bấm thanks nữa chứ, tại em ham hỏi quá nên quên mất, xin thầy lượng thứ.
    Mặt dày hỏi thầy câu nữa
    "64-bits little-endian word" có nghĩa là từ 64 bit có trọng LSB ở cuối phải không ạ?
    Little Endian:
    Base Address+0 Byte0
    Base Address+1 Byte1
    Base Address+2 Byte2
    Base Address+3 Byte3
    Big Endian:
    Base Address+0 Byte3
    Base Address+1 Byte2
    Base Address+2 Byte1
    Base Address+3 Byte0

    Leave a comment:


  • dhp11591
    replied
    Hi, tự nhiên làm phiền thầy mà còn chưa bấm thanks nữa chứ, tại em ham hỏi quá nên quên mất, xin thầy lượng thứ.
    Mặt dày hỏi thầy câu nữa
    "64-bits little-endian word" có nghĩa là từ 64 bit có LSB ở cuối phải không ạ?
    Last edited by dhp11591; 28-08-2012, 23:45.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Em cám ơn thầy nhiều lắm lắm
    Sau khi thầy thầy giải thích, em đã hiểu về branch, tag, Call-ID.
    Em đã thử bắt gói khi 1 account đăng nhập và khi 2 máy gọi cho nhau, nó vẫn yêu cầu branch và tag nên khi em cắm mạch vào, mạch gửi 1 request REGISTER đến Proxy Sever nhưng sever không thèm gửi lại 1 respond 401 Unauthorized đòi mật khẩu ạ
    Vậy UA generate branh, tag, Call-ID bằng giải thuật nào, đầu vào nó là gì ạ? Nó có liên quan đến MD5 không ạ? Em thấy nó cũng lằng nhằng như mấy chuỗi ký tự mã hóa username-password trong bản tin REGISTER thứ 2
    Call-ID là gì cũng được, miễn là duy nhất.
    Branch: cũng không được trùng và bắt đầu bằng "z9hG4bK". Tham khảo thêm http://www.ietf.org/rfc/rfc3261.txt mục 8.1.1.7
    Tag: trường From bắt buộc có Tag, trường To của mesage không nằm trong 1 dialog không được có Tag, nhìn chung, khi em gửi đi bản tin REGISTER không cần Tag trong trường To. Cách sinh ra Tag tự người lập trình quyết định.
    Tham khảo thêm http://www.ietf.org/rfc/rfc3261.txt để biết, hơi khó hiểu nhưng đây là khuyến nghị chính thức, mọi hệ thống đều theo RFC này.
    May mà hồi trước dạy VoIP nên mới trả lời được các vấn đề của em.
    Last edited by nttam79; 28-08-2012, 21:56.

    Leave a comment:


  • dhp11591
    replied
    Em cám ơn thầy nhiều lắm lắm
    Sau khi thầy thầy giải thích, em đã hiểu về branch, tag, Call-ID.
    Em đã thử bắt gói khi 1 account đăng nhập và khi 2 máy gọi cho nhau, nó vẫn yêu cầu branch và tag nên khi em cắm mạch vào, mạch gửi 1 request REGISTER đến Proxy Sever nhưng sever không thèm gửi lại 1 respond 401 Unauthorized đòi mật khẩu ạ
    Vậy UA generate branh, tag, Call-ID bằng giải thuật nào, đầu vào nó là gì ạ? Nó có liên quan đến MD5 không ạ? Em thấy nó cũng lằng nhằng như mấy chuỗi ký tự mã hóa username-password trong bản tin REGISTER thứ 2

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Dạ UA ạ. Em định cho nó cantact với 1 cái SIP sever cài trên 1 máy trong LAN
    Ký tự xuống dòng, nó là "\r\n" hay "\n\r" ạ? Em thấy nó đều là xuống dòng và về đầu dòng.
    Trong bản tin SIP, em thấy trong 1 số trường có tag và branch, ý nghĩa của nó là gì ạ? Các con số đó tính như thế nào, có quan trọng không ạ?
    Hix, em dùng wireshark thì thấy có những bản tin > 700 byte (có tag và branch) mà nhận hay gửi chúng thì phải chia ra, em sợ chia ra rồi server nhận đc lại không biết ghép lại, vì 1 mình 1 chuẩn. Mắc quá thầy ơi...
    Là \r\n
    Branch nằm trong trường VIA dùng để phân biệt các transaction. Một transaction là bao gồm bản tin request và các bản tin response cho nó.
    Ví dụ khi UA gửi 1 bản tin INVITE, nó sẽ nhận được nhiều bản tin response cho bản tin INVITE đó từ các Proxy server/ Redirect Server trước khi nhận được bản tin từ UA mà nó muốn gọi. Như vậy bản tin INVITE trên và tất cả các bản tin response cho nó đều có chung Branch.
    Tag nằm ở trường From và To, nhìn chung, From Tag, To Tag và Call-ID dùng để phân biệt các Dialog SIP. Một Dialog có thể hiểu là 1 cuộc trao đổi giữa 2 thành phần trong mạng. Ví dụ trong một cuộc gọi SIP giữa 2 UA thì bản tin INVITE và responses của nó là 1 transaction, bản tin BYE và responses cho nó cũng là 1 transaction, nhưng cả 2 transaction thuộc cùng 1 Dialog.
    Tuy nhiên cách dùng Tag thì rắc rối hơn, ví dụ UA gửi đi 1 bản tin INVITE, các porxy trên mạng đều response cho nó, trong trường hợp này Tag của trường To trong mỗi response lại khác nhau.
    Tag trong From sinh ra bởi Caller. Trong khi Tag trong To sinh ra bởi Callee
    Nếu mô hình mạng đơn giản thì không cần Tag và Branch cũng được.
    SIP message được gửi bằng UDP. Do đó một bản tin SIP nên nằm trong 1 gói UDP độc lập. Em có thể mở rộng buffer nếu kích thước bản tin lớn.

    Leave a comment:


  • dhp11591
    replied
    Dạ UA ạ. Em định cho nó cantact với 1 cái SIP sever cài trên 1 máy trong LAN
    Ký tự xuống dòng, nó là "\r\n" hay "\n\r" ạ? Em thấy nó đều là xuống dòng và về đầu dòng.
    Trong bản tin SIP, em thấy trong 1 số trường có tag và branch, ý nghĩa của nó là gì ạ? Các con số đó tính như thế nào, có quan trọng không ạ?
    Hix, em dùng wireshark thì thấy có những bản tin > 700 byte (có tag và branch) mà nhận hay gửi chúng thì phải chia ra, em sợ chia ra rồi server nhận đc lại không biết ghép lại, vì 1 mình 1 chuẩn. Mắc quá thầy ơi...

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Em cảm ơn thầy ạ.
    Em cũng vừa viết lại theo cách đó. Em đang viết SIP, viêt 9 lần rồi mà chưa thành công hẳn hoi.
    Mà em cũng chưa hiểu, nếu lưu data vào PROGMEM thì làm sao cập nhật được ạ? Ý em là khi khai báo 1 mảng (1 vùng nhớ) cho 1 bộ đệm lưu những thứ cần thiết, thì phải khởi tạo luôn cho nó. Mà đã khởi tạo rồi thì không cập nhật được ạ. Em dịch, nó cứ báo lỗi read-only
    Cuối cùng, em đành ngậm ngùi lưu qua EEPROM, chấp nhận cái giới hạn 100.000 lần ghi/xóa của nó để có cái đề mô
    Vậy là đến giai đoạn bật wireshark bắt gói nghiền ngẫm như chuyên gia, có điều em nghiền 1 hồi mà vẫn chưa ngẫm ra tại sao bản tin của em lại có chỗ bị bôi vàng chóe????
    Có phải do trong các URL, em viết thừa port 5060 của nó không ạ? Nhũng chỗ nào nên viết, nhưng chỗ nào không đựoc viết, xin thầy chỉ bảo cho em.

    Hix, nếu post của em làm loãng 2pic, xin thầy và các anh thông cảm. Xin MOD đừng động đến

    //-----------------------------------------
    //Hóa ra header của SIP cũng kết thúc bằng 1 dòng trống, em không có cái đấy, wireshark nó chỉ cho mà lúc nãy không chịu đọc
    Ừ, bản tin SIP gần giống HTTP, header kết thúc bằng \n\r\n\r.
    Mà em dùng ATmega đóng vai trò gì trong SIP vậy? UA hay proxy/register server, hay chỉ để test các bản tin SIP.

    Leave a comment:


  • dhp11591
    replied
    Em cảm ơn thầy ạ.
    Em cũng vừa viết lại theo cách đó. Em đang viết SIP, viêt 9 lần rồi mà chưa thành công hẳn hoi.
    Mà em cũng chưa hiểu, nếu lưu data vào PROGMEM thì làm sao cập nhật được ạ? Ý em là khi khai báo 1 mảng (1 vùng nhớ) cho 1 bộ đệm lưu những thứ cần thiết, thì phải khởi tạo luôn cho nó. Mà đã khởi tạo rồi thì không cập nhật được ạ. Em dịch, nó cứ báo lỗi read-only
    Cuối cùng, em đành ngậm ngùi lưu qua EEPROM, chấp nhận cái giới hạn 100.000 lần ghi/xóa của nó để có cái đề mô
    Vậy là đến giai đoạn bật wireshark bắt gói nghiền ngẫm như chuyên gia, có điều em nghiền 1 hồi mà vẫn chưa ngẫm ra tại sao bản tin của em lại có chỗ bị bôi vàng chóe????
    Có phải do trong các URL, em viết thừa port 5060 của nó không ạ? Nhũng chỗ nào nên viết, nhưng chỗ nào không đựoc viết, xin thầy chỉ bảo cho em.

    Hix, nếu post của em làm loãng 2pic, xin thầy và các anh thông cảm. Xin MOD đừng động đến

    //-----------------------------------------
    //Hóa ra header của SIP cũng kết thúc bằng 1 dòng trống, em không có cái đấy, wireshark nó chỉ cho mà lúc nãy không chịu đọc
    Last edited by dhp11591; 24-08-2012, 18:25.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Thầy ơi, có chỗ này em không hiểu, xin thầy giải đáp cho em:
    Em đang viết 1 giao thức chạy qua UDP, em thấy có 1 vấn đề là khi nhận được 1 bản tin và phải đáp ứng lại 1 bản tin thì bản tin nhận đc đang nằm trên buffer và bản tin đáp ứng phải đc viết nháp ở 1 vùng nhớ khác rồi copy về vùng nhớ bắt đầu bởi ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + 8. Mà RAM của ATmega32 khá nhỏ => phải viết trên ROM, nhưng ROM là bộ nhớ chỉ đọc, vậy viết nháp nó như thế nào ạ?
    Mà sao em vẫn dùng hàm strcat() với chuỗi prog_char mà không báo lỗi ạ?
    Xin thầy giúp em với.
    Em cám ơn thầy ạ.
    Không nên viết nháp gì cả: khi nhận bản tin đến trong buffer, em xử lý và lưu lại các giá trị cần thiết xong -> bản tin trả lời ghi dè lên luôn trên buffer.

    Leave a comment:


  • nttam79
    replied
    Nguyên văn bởi dhp11591 Xem bài viết
    Các anh ơi, cho em hỏi vài điều:
    1) Trong hàm httpHeaderGetField(), thầy Tâm tính headerLen = (rqst->header) - (rqst->body) - 4;
    Em nghĩ kết quả của nó là số âm. Vậy sao vẫn dùng được ạ?
    2) Biến lưu trong Program Memory (kiểu prog_char) thì dùng hàm nào để thay đổi giá trị của nó ạ? Em đọc thư viện pgmspace.h với user_manual mà không thấy nói gì đến. Liệu nó có thể thay đổi đựoc không ạ? Hay là thay đổi nó hoàn toàn giống với biến trong SRAM? Em dùng ATmega32.
    Xin các anh chỉ giáo. Tks
    1-Chỗ này dường như tôi sai: phải là headerLen = (rqst->body) - (rqst->header) - 4;
    Vẫn được vì headerLen khai báo là unsigned và chỉ dùng để giới hạn số byte tìm kiếm, chỉ có là phải tìm lâu hơn thôi.
    2-Biến lưu trong Program Memory về nguyên tắc là không thay đổi được (thực ra trong AVR vẫn có thể dùng lệnh ghi flash để thay đổi nó). Nếu đã muốn thay đổi thì không nên khai báo thuộc Program Memory.

    Leave a comment:

Về tác giả

Collapse

nttam79 Tìm hiểu thêm về nttam79

Bài viết mới nhất

Collapse

Đang tải...
X