1 /* This file contains common process functions. */
2 #include "tx_api.h"
3 #include "nx_api.h"
4
5 #if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN)
6 #include "nx_websocket_client.h"
7
8 #define TEST_CONNECT_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
9 #define TEST_CONNECT_GUID_SIZE (sizeof(TEST_CONNECT_GUID) - 1)
10 #define TEST_CONNECT_DIGEST_SIZE 20 /* The length of SHA-1 hash is 20 bytes */
11 #define TEST_CONNECT_KEY_SIZE 32 /* Make it larger than the minimum length (28 bytes )for the encoded key */
12
13 static UCHAR connect_key[TEST_CONNECT_KEY_SIZE];
14 static UINT connect_key_size;
15
_server_connect_response_process(NX_PACKET * packet_ptr)16 UINT _server_connect_response_process(NX_PACKET *packet_ptr)
17 {
18 UCHAR *buffer_ptr;
19 UINT offset = 0;
20 UCHAR *field_name;
21 UINT field_name_length;
22 UCHAR *field_value;
23 UINT field_value_length;
24 NX_SHA1 SH;
25 UCHAR digest[TEST_CONNECT_DIGEST_SIZE];
26
27 buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
28
29 /* Skip over the first Command line (GET /xxx HTTP/1.1\r\n). */
30 while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) &&
31 (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n'))
32 {
33 buffer_ptr++;
34 offset++;
35 }
36
37 /* Skip over the CR,LF. */
38 buffer_ptr += 2;
39 offset += 2;
40
41 /* Skip over the first Host line (Host: xxx\r\n). */
42 while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) &&
43 (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n'))
44 {
45 buffer_ptr++;
46 offset++;
47 }
48
49 /* Skip over the CR,LF. */
50 buffer_ptr += 2;
51 offset += 2;
52
53 /* Loop until we find the "cr,lf,cr,lf" token. */
54 while (((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != 0))
55 {
56
57 /* Check for the <cr,lf,cr,lf> token. This signals a blank line, which also
58 specifies the start of the content. */
59 if ((*buffer_ptr == '\r') &&
60 (*(buffer_ptr + 1) == '\n'))
61 {
62
63 /* Adjust the offset. */
64 offset = offset + 2;
65 break;
66 }
67
68 /* We haven't seen the <cr,lf,cr,lf> so we are still processing header data.
69 Extract the field name and it's value. */
70 field_name = buffer_ptr;
71 field_name_length = 0;
72
73 /* Look for the ':' that separates the field name from its value. */
74 while(*buffer_ptr != ':')
75 {
76 buffer_ptr++;
77 field_name_length++;
78 }
79 offset += field_name_length;
80
81 /* Skip ':'. */
82 buffer_ptr++;
83 offset++;
84
85 /* Now skip over white space. */
86 while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
87 {
88 buffer_ptr++;
89 offset++;
90 }
91
92 /* Now get the field value. */
93 field_value = buffer_ptr;
94 field_value_length = 0;
95
96 /* Loop until we see a <CR, LF>. */
97 while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '\r') && (*(buffer_ptr+1) != '\n'))
98 {
99 buffer_ptr++;
100 field_value_length++;
101 }
102 offset += field_value_length;
103
104 /* Skip over the CR,LF. */
105 buffer_ptr += 2;
106 offset += 2;
107
108 /* Check the upgrade. */
109 if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1) == NX_SUCCESS)
110 {
111 if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"websocket", sizeof("websocket") - 1))
112 {
113 return(NX_WEBSOCKET_INVALID_PACKET);
114 }
115 }
116 else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Connection", sizeof("Connection") - 1) == NX_SUCCESS)
117 {
118 if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1))
119 {
120 return(NX_WEBSOCKET_INVALID_PACKET);
121 }
122 }
123 else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Sec-WebSocket-Key", sizeof("Sec-WebSocket-Key") - 1) == NX_SUCCESS)
124 {
125
126 /* Calculate the SHA-1 hash of the concatenation of the client key and the Globally Unique Identifier (GUID)
127 Referenced in RFC 6455, Section 1.3, Page 6 */
128 _nx_sha1_initialize(&SH);
129 _nx_sha1_update(&SH, field_value, field_value_length);
130 _nx_sha1_update(&SH, (UCHAR*)TEST_CONNECT_GUID, TEST_CONNECT_GUID_SIZE);
131 _nx_sha1_digest_calculate(&SH, digest);
132
133 /* Encode the hash and compare it with the field value from the server. */
134 _nx_utility_base64_encode(digest, TEST_CONNECT_DIGEST_SIZE, connect_key, TEST_CONNECT_KEY_SIZE, &connect_key_size);
135 }
136 }
137
138 /* Check if the all fields are processed. */
139 if (offset != packet_ptr -> nx_packet_length)
140 {
141 return(NX_WEBSOCKET_INVALID_PACKET);
142 }
143
144 return(NX_SUCCESS);
145 }
146
147 #endif
148
SET_ERROR_COUNTER(ULONG * error_counter,CHAR * filename,int line_number)149 void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number)
150 {
151 *error_counter = (*error_counter) + 1;
152
153 printf("Error: File %s:%d\n", filename, line_number);
154 }
155
156