iosignal 1.4.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +247 -240
  2. package/auth_file.json +13 -13
  3. package/auth_file.mjs +23 -23
  4. package/dist/iosignal.cjs +1 -1
  5. package/dist/iosignal.esm.js +2 -2
  6. package/dist/iosignal.esm.js.map +1 -1
  7. package/dist/iosignal.min.js +2 -2
  8. package/dist/iosignal.min.js.map +1 -1
  9. package/index.js +19 -19
  10. package/indexWebBrowser.js +13 -13
  11. package/package.json +59 -60
  12. package/rollup.config.js +69 -69
  13. package/src/api/RedisAPI.js +68 -68
  14. package/src/api/api_constant.js +7 -7
  15. package/src/api/api_reply.js +34 -34
  16. package/src/api/api_sudo.js +96 -96
  17. package/src/auth/Auth_Env.js +78 -78
  18. package/src/auth/Auth_File.js +75 -75
  19. package/src/auth/Auth_Redis.js +50 -50
  20. package/src/auth/BohoAuth.js +168 -168
  21. package/src/client/CongPacket.js +150 -150
  22. package/src/client/IOCongSocket.js +88 -88
  23. package/src/client/IOCore.js +851 -851
  24. package/src/client/IOWS.js +81 -81
  25. package/src/client/IOWebSocket.js +107 -95
  26. package/src/common/constants.js +159 -159
  27. package/src/common/payload.js +82 -82
  28. package/src/common/quotaTable.js +68 -68
  29. package/src/common/util.js +61 -61
  30. package/src/server/FileLogger.js +30 -30
  31. package/src/server/Manager.js +449 -449
  32. package/src/server/Metric.js +154 -154
  33. package/src/server/Server.js +166 -148
  34. package/src/server/ServerRemote.js +227 -227
  35. package/src/server/ServerRemoteCore.js +467 -467
  36. package/src/server/serverOption.js +56 -55
  37. package/test-browser/favicon.ico +0 -0
  38. package/test-browser/index.html +92 -92
  39. package/test-browser/server.js +11 -11
  40. package/test-client-nodejs/client.cjs +17 -17
  41. package/test-client-nodejs/client.mjs +17 -17
  42. package/test-client-nodejs/client_api_reply.mjs +15 -15
  43. package/test-client-nodejs/stateChange.mjs +19 -19
  44. package/test-server/server-Auth_Env.js +19 -19
  45. package/test-server/server-Auth_File.js +12 -12
  46. package/test-server/server-api_reply.js +6 -6
  47. package/test-server/server-api_sudo.js +7 -7
  48. package/test-server/server-commonjs.cjs +8 -8
  49. package/test-server/server-esm.mjs +19 -19
  50. package/test-server/simple-server.mjs +11 -11
  51. package/test-signal-payloadType/signalPack.js +34 -34
  52. package/test-signal-payloadType/signaling.js +60 -60
@@ -1,81 +1,81 @@
1
- import { IOCore } from "./IOCore.js";
2
- import { WebSocket } from "ws";
3
-
4
- // Node.js 'ws' websocket
5
- export class IOWS extends IOCore{
6
- constructor(url ) {
7
- super(url);
8
- if(url) this.open();
9
- }
10
-
11
-
12
-
13
- close() {
14
- if(this.socket ){
15
- this.socket.onclose = null
16
- this.socket.onmessage = null
17
- this.socket.onerror = null
18
- this.socket.close();
19
- this.socket = null;
20
- }
21
- this.emit('close')
22
- }
23
-
24
-
25
-
26
- stop() {
27
- this.close()
28
- clearInterval(this.connectionCheckerIntervalID);
29
- this.connectionCheckerIntervalID = null
30
- }
31
-
32
- keepAlive() {
33
- if ( !this.socket || this.socket?.readyState === 3 ) { //closed
34
- this.open();
35
- }
36
- }
37
-
38
-
39
- createConnection(url){
40
- // node WebSocket
41
- this.socket = new WebSocket ( url );
42
- this.stateChange('opening')
43
-
44
- this.socket.onopen = () => {
45
- this.socket.on('message', this.onWebSocketMessage.bind(this) );
46
- this.emit('open' );
47
- };
48
-
49
- this.socket.onerror = (e)=>{
50
- this.emit('error', e)
51
- }
52
-
53
- this.socket.onclose = ()=>{
54
- this.emit('close' );
55
- }
56
- }
57
-
58
- onWebSocketMessage( data ) {
59
- this.rxCounter++;
60
- this.lastTxRxTime = Date.now();
61
- this.rxBytes += data.byteLength
62
- this.emit('socket_data', data );
63
- }
64
-
65
- socket_send(data) {
66
- if( this.socket?.readyState === 1 ){ //open
67
- // console.log('websocket send', data)
68
- this.socket.send( data )
69
- this.txCounter++;
70
- this.txBytes += data.byteLength
71
- this.lastTxRxTime = Date.now();
72
- }else{
73
- console.log('')
74
- }
75
- }
76
-
77
- }
78
-
79
-
80
-
81
-
1
+ import { IOCore } from "./IOCore.js";
2
+ import { WebSocket } from "ws";
3
+
4
+ // Node.js 'ws' websocket
5
+ export class IOWS extends IOCore{
6
+ constructor(url ) {
7
+ super(url);
8
+ if(url) this.open();
9
+ }
10
+
11
+
12
+
13
+ close() {
14
+ if(this.socket ){
15
+ this.socket.onclose = null
16
+ this.socket.onmessage = null
17
+ this.socket.onerror = null
18
+ this.socket.close();
19
+ this.socket = null;
20
+ }
21
+ this.emit('close')
22
+ }
23
+
24
+
25
+
26
+ stop() {
27
+ this.close()
28
+ clearInterval(this.connectionCheckerIntervalID);
29
+ this.connectionCheckerIntervalID = null
30
+ }
31
+
32
+ keepAlive() {
33
+ if ( !this.socket || this.socket?.readyState === 3 ) { //closed
34
+ this.open();
35
+ }
36
+ }
37
+
38
+
39
+ createConnection(url){
40
+ // node WebSocket
41
+ this.socket = new WebSocket ( url );
42
+ this.stateChange('opening')
43
+
44
+ this.socket.onopen = () => {
45
+ this.socket.on('message', this.onWebSocketMessage.bind(this) );
46
+ this.emit('open' );
47
+ };
48
+
49
+ this.socket.onerror = (e)=>{
50
+ this.emit('error', e)
51
+ }
52
+
53
+ this.socket.onclose = ()=>{
54
+ this.emit('close' );
55
+ }
56
+ }
57
+
58
+ onWebSocketMessage( data ) {
59
+ this.rxCounter++;
60
+ this.lastTxRxTime = Date.now();
61
+ this.rxBytes += data.byteLength
62
+ this.emit('socket_data', data );
63
+ }
64
+
65
+ socket_send(data) {
66
+ if( this.socket?.readyState === 1 ){ //open
67
+ // console.log('websocket send', data)
68
+ this.socket.send( data )
69
+ this.txCounter++;
70
+ this.txBytes += data.byteLength
71
+ this.lastTxRxTime = Date.now();
72
+ }else{
73
+ console.log('')
74
+ }
75
+ }
76
+
77
+ }
78
+
79
+
80
+
81
+
@@ -1,95 +1,107 @@
1
- import { IOCore } from "./IOCore.js";
2
- import { Buffer } from 'meta-buffer-pack'
3
- export { Boho, RAND, BohoMsg, Meta, MetaSize , sha256, MBP, Buffer } from 'boho'
4
- export * from '../common/constants.js'
5
-
6
- // Browser WebSocket
7
- export class IO extends IOCore{
8
- constructor(url ) {
9
- super(url);
10
- document.addEventListener('visibilitychange', this.browserVisiblePing.bind(this));
11
- if(url) this.open();
12
- }
13
-
14
- browserVisiblePing(){
15
- if (document.visibilityState === 'visible') {
16
- this.ping()
17
- }
18
- }
19
-
20
-
21
- close() {
22
- if(this.socket ){
23
- this.socket.onclose = null
24
- this.socket.onmessage = null
25
- this.socket.onerror = null
26
- this.socket.close();
27
- this.socket = null;
28
- }
29
- this.emit('close')
30
- }
31
-
32
-
33
- stop(){
34
- this.close()
35
- clearInterval(this.connectionCheckerIntervalID);
36
- this.connectionCheckerIntervalID = null
37
- }
38
-
39
-
40
- keepAlive() {
41
- if ( !this.socket || this.socket?.readyState === 3 ) { //closed
42
- this.open();
43
- }
44
- }
45
-
46
- createConnection(url){
47
- // Web Browser WebSocket
48
- this.socket = new WebSocket (url );
49
- this.stateChange('opening')
50
-
51
- this.socket.binaryType = "arraybuffer"
52
- this.socket.onopen = () => {
53
- this.socket.onmessage = this.onWebSocketMessage.bind(this) ;
54
- this.emit('open' );
55
- };
56
-
57
- this.socket.onerror = (e)=>{
58
- this.emit('error', e)
59
- }
60
-
61
- this.socket.onclose = ()=>{
62
- this.emit('close' );
63
- }
64
- }
65
-
66
- onWebSocketMessage( event ) {
67
- this.rxCounter++;
68
- this.lastTxRxTime = Date.now();
69
- let buffer;
70
-
71
- // if( event.data instanceof ArrayBuffer ){
72
- // //binary frame
73
- // }else{
74
- // //text frame
75
- // }
76
- buffer = Buffer.from( event.data )
77
- this.rxBytes += buffer.byteLength
78
-
79
- this.emit('socket_data', buffer );
80
- }
81
-
82
- socket_send(data) {
83
- if( this.socket?.readyState === 1 ){ //open
84
- // console.log('websocket send', data)
85
- this.socket.send( data )
86
- this.txCounter++;
87
- this.txBytes += data.byteLength
88
- this.lastTxRxTime = Date.now();
89
- }else{
90
- console.log('.')
91
- }
92
- }
93
-
94
- }
95
-
1
+ import { IOCore } from "./IOCore.js";
2
+ import { Buffer } from 'meta-buffer-pack'
3
+ export { Boho, RAND, BohoMsg, Meta, MetaSize, sha256, MBP, Buffer } from 'boho'
4
+ export * from '../common/constants.js'
5
+
6
+ // Browser WebSocket
7
+ export class IO extends IOCore {
8
+ static binaryType = "arraybuffer"
9
+
10
+ constructor(url) {
11
+ super(url);
12
+ document.addEventListener('visibilitychange', this.browserVisiblePing.bind(this));
13
+ if (url) this.open();
14
+ }
15
+
16
+ browserVisiblePing() {
17
+ if (document.visibilityState === 'visible') {
18
+ this.ping()
19
+ }
20
+ }
21
+
22
+
23
+ close() {
24
+ if (this.socket) {
25
+ this.socket.onclose = null
26
+ this.socket.onmessage = null
27
+ this.socket.onerror = null
28
+ this.socket.close();
29
+ this.socket = null;
30
+ }
31
+ this.emit('close')
32
+ }
33
+
34
+
35
+ stop() {
36
+ this.close()
37
+ clearInterval(this.connectionCheckerIntervalID);
38
+ this.connectionCheckerIntervalID = null
39
+ }
40
+
41
+
42
+ keepAlive() {
43
+ if (!this.socket || this.socket?.readyState === 3) { //closed
44
+ this.open();
45
+ }
46
+ }
47
+
48
+
49
+
50
+ createConnection(url) {
51
+ // Web Browser WebSocket
52
+ this.socket = new WebSocket(url);
53
+ this.socket.binaryType = IO.binaryType
54
+
55
+ this.stateChange('opening')
56
+
57
+ this.socket.onopen = () => {
58
+ if (this.socket.binaryType == "arraybuffer") {
59
+ this.socket.onmessage = this.onWebSocketMessage.bind(this);
60
+ } else { // blob
61
+ this.socket.onmessage = this.onWebSocketMessageBlob.bind(this);
62
+ }
63
+ this.emit('open');
64
+ };
65
+
66
+ this.socket.onerror = (e) => {
67
+ this.emit('error', e)
68
+ }
69
+
70
+ this.socket.onclose = () => {
71
+ this.emit('close');
72
+ }
73
+ }
74
+
75
+ onWebSocketMessage(event) {
76
+ // event.data is arrayBuffer
77
+ this.rxCounter++;
78
+ this.lastTxRxTime = Date.now();
79
+ let buffer = Buffer.from(event.data)
80
+ this.rxBytes += buffer.byteLength
81
+ this.emit('socket_data', buffer);
82
+ }
83
+
84
+ async onWebSocketMessageBlob(event) {
85
+ // event.data is Blob
86
+ this.rxCounter++;
87
+ this.lastTxRxTime = Date.now();
88
+ let ab = await event.data.arrayBuffer()
89
+ let buffer = Buffer.from(ab)
90
+ this.rxBytes += buffer.byteLength
91
+ this.emit('socket_data', buffer);
92
+ }
93
+
94
+ socket_send(data) {
95
+ if (this.socket?.readyState === 1) { //open
96
+ // console.log('websocket send', data)
97
+ this.socket.send(data)
98
+ this.txCounter++;
99
+ this.txBytes += data.byteLength
100
+ this.lastTxRxTime = Date.now();
101
+ } else {
102
+ console.log('.')
103
+ }
104
+ }
105
+
106
+ }
107
+
@@ -1,159 +1,159 @@
1
-
2
- // IOclient state
3
- export const STATES = {
4
- OPENING: 0,
5
- OPEN: 1,
6
- CLOSING: 2,
7
- CLOSED: 3,
8
- SERVER_READY: 4,
9
- AUTH_FAIL: 5,
10
- AUTH_READY: 6,
11
- READY: 7,
12
- REDIRECTING: 8
13
- }
14
- for (let c in STATES) { STATES[STATES[c]] = c }
15
-
16
- // server side client state
17
- export const CLIENT_STATE = {
18
- INIT: 0,
19
- SENT_SERVER_READY: 1,
20
- RECV_AUTH_REQ: 2,
21
- SENT_SERVER_NONCE: 3,
22
- RECV_AUTH_HMAC: 4,
23
- AUTH_FAIL: 5,
24
- AUTH_READY: 6,
25
- CID_READY: 7
26
- }
27
- for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
28
-
29
- export let ENC_MODE = {
30
- NO: 0,
31
- YES: 1,
32
- AUTO: 2
33
- }
34
-
35
- for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
36
-
37
-
38
- export const SIZE_LIMIT = {
39
- TAG_LEN1: 255,
40
- TAG_LEN2: 65535,
41
- CONNECTION_CHECKER_PERIOD: 3000,
42
- PROMISE_TIMEOUT: 5000,
43
- DID: 8,
44
- CID: 12
45
- }
46
-
47
- export let PAYLOAD_TYPE = {
48
- EMPTY: 0,
49
- TEXT: 1,
50
- BINARY: 2,
51
- OBJECT: 3, // one stringify able object. no buffer.
52
- MJSON: 4, // multiple stringify able obejct. JSON string. with top levle array , no buffer
53
- MBA: 5 // "meta_buffer_arguments" arbitary types. buffer included.
54
- }
55
- for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
56
- // console.log( PAYLOAD_TYPE )
57
-
58
- // MJSON: multiple arguments
59
- // accepet only string, number, root depth js primittive object,
60
- // unpack and will send to receiver handler with multiple params.
61
-
62
- // MBA: buffer pack of multiple arguments. check "meta-buffer-pack" module.
63
- // MBA: when armuents includes raw Buffer( TypedArray )
64
-
65
- // IO message pack one byte header.
66
- export let IOMsg = {
67
-
68
- /*
69
- * 0~127dec. reserved. for text stream.
70
- * 0~31: control code
71
- * 32~126: ascii charactor
72
- * 127: DEL
73
- */
74
-
75
- // ADMIN_REQ: 0xA0,
76
-
77
- // DO NOT USE: 0xB0~ 0xBF
78
- // Boho module using this numbers.
79
- // AUTH_REQ : 0xB0,
80
- // AUTH_NONCE: 0xB1,
81
- // AUTH_HMAC: 0xB2,
82
- // AUTH_ACK: 0xB3,
83
- // AUTH_FAIL: 0xB4,
84
- // AUTH_EXT: 0xB5,
85
- // ENC_PACK : 0xB6,
86
- // ENC_E2E : 0xB7,
87
- // ENC_488 : 0xB8
88
- // reserved ~0xBF
89
-
90
- // C. IO status contorl.
91
- SERVER_READY: 0xC0,
92
- CID_REQ: 0xC1,
93
- CID_RES: 0xC2,
94
- QUOTA_LEVEL: 0xC3,
95
- SERVER_CLEAR_AUTH: 0xC4,
96
- SERVER_REDIRECT: 0xC5,
97
-
98
- // ..
99
- LOOP: 0xCB,
100
- ECHO: 0xCC,
101
- PING: 0xCD,
102
- PONG: 0xCE,
103
- CLOSE: 0xCF,
104
- // ~CF
105
-
106
-
107
- // D. IO data signaling
108
- SIGNAL: 0xD0,
109
- SIGNAL_REQ: 0xD1,
110
- SIGNAL_E2E: 0xD2,
111
- SUBSCRIBE: 0xD3,
112
- SUBSCRIBE_REQ: 0xD4,
113
- UNSUBSCRIBE: 0xD5,
114
- SERVER_SIGNAL: 0xD6,
115
-
116
- // ..
117
- IAM: 0xD9,
118
- IAM_RES: 0xDA,
119
-
120
- //..
121
- SET: 0xDB, //
122
- RESPONSE_CODE: 0xDC,
123
- RESPONSE_MBP: 0xDD,
124
-
125
- REQUEST: 0xDE, //client public
126
- RESPONSE: 0xDF,
127
- // ~DF
128
-
129
-
130
- // F. Framing Flow control related framing protocol.(CongPacket)
131
- FLOW_MODE: 0xF0,
132
- WAIT: 0xF1,
133
- RESUME: 0xF2,
134
- //..
135
- TIME_OUT: 0xFD,
136
- OVER_SIZE: 0xFE,
137
- OVER_FLOW: 0xFF
138
-
139
- }
140
-
141
- for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
142
-
143
- // console.log( IOMsg );
144
-
145
-
146
- export const API_TYPE = {
147
- 'REQUEST_RESPONSE': 'requet_response',
148
- 'ONE_WAY': 'one_way'
149
- }
150
-
151
-
152
-
153
- // api response status code
154
- export const STATUS = {
155
- OK: 0,
156
- //0~127: success
157
- //128~255: fail
158
- ERROR: 255
159
- }
1
+
2
+ // IOclient state
3
+ export const STATES = {
4
+ OPENING: 0,
5
+ OPEN: 1,
6
+ CLOSING: 2,
7
+ CLOSED: 3,
8
+ SERVER_READY: 4,
9
+ AUTH_FAIL: 5,
10
+ AUTH_READY: 6,
11
+ READY: 7,
12
+ REDIRECTING: 8
13
+ }
14
+ for (let c in STATES) { STATES[STATES[c]] = c }
15
+
16
+ // server side client state
17
+ export const CLIENT_STATE = {
18
+ INIT: 0,
19
+ SENT_SERVER_READY: 1,
20
+ RECV_AUTH_REQ: 2,
21
+ SENT_SERVER_NONCE: 3,
22
+ RECV_AUTH_HMAC: 4,
23
+ AUTH_FAIL: 5,
24
+ AUTH_READY: 6,
25
+ CID_READY: 7
26
+ }
27
+ for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
28
+
29
+ export let ENC_MODE = {
30
+ NO: 0,
31
+ YES: 1,
32
+ AUTO: 2
33
+ }
34
+
35
+ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
36
+
37
+
38
+ export const SIZE_LIMIT = {
39
+ TAG_LEN1: 255,
40
+ TAG_LEN2: 65535,
41
+ CONNECTION_CHECKER_PERIOD: 3000,
42
+ PROMISE_TIMEOUT: 5000,
43
+ DID: 8,
44
+ CID: 12
45
+ }
46
+
47
+ export let PAYLOAD_TYPE = {
48
+ EMPTY: 0,
49
+ TEXT: 1,
50
+ BINARY: 2,
51
+ OBJECT: 3, // one stringify able object. no buffer.
52
+ MJSON: 4, // multiple stringify able obejct. JSON string. with top levle array , no buffer
53
+ MBA: 5 // "meta_buffer_arguments" arbitary types. buffer included.
54
+ }
55
+ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
56
+ // console.log( PAYLOAD_TYPE )
57
+
58
+ // MJSON: multiple arguments
59
+ // accepet only string, number, root depth js primittive object,
60
+ // unpack and will send to receiver handler with multiple params.
61
+
62
+ // MBA: buffer pack of multiple arguments. check "meta-buffer-pack" module.
63
+ // MBA: when armuents includes raw Buffer( TypedArray )
64
+
65
+ // IO message pack one byte header.
66
+ export let IOMsg = {
67
+
68
+ /*
69
+ * 0~127dec. reserved. for text stream.
70
+ * 0~31: control code
71
+ * 32~126: ascii charactor
72
+ * 127: DEL
73
+ */
74
+
75
+ // ADMIN_REQ: 0xA0,
76
+
77
+ // DO NOT USE: 0xB0~ 0xBF
78
+ // Boho module using this numbers.
79
+ // AUTH_REQ : 0xB0,
80
+ // AUTH_NONCE: 0xB1,
81
+ // AUTH_HMAC: 0xB2,
82
+ // AUTH_ACK: 0xB3,
83
+ // AUTH_FAIL: 0xB4,
84
+ // AUTH_EXT: 0xB5,
85
+ // ENC_PACK : 0xB6,
86
+ // ENC_E2E : 0xB7,
87
+ // ENC_488 : 0xB8
88
+ // reserved ~0xBF
89
+
90
+ // C. IO status contorl.
91
+ SERVER_READY: 0xC0,
92
+ CID_REQ: 0xC1,
93
+ CID_RES: 0xC2,
94
+ QUOTA_LEVEL: 0xC3,
95
+ SERVER_CLEAR_AUTH: 0xC4,
96
+ SERVER_REDIRECT: 0xC5,
97
+
98
+ // ..
99
+ LOOP: 0xCB,
100
+ ECHO: 0xCC,
101
+ PING: 0xCD,
102
+ PONG: 0xCE,
103
+ CLOSE: 0xCF,
104
+ // ~CF
105
+
106
+
107
+ // D. IO data signaling
108
+ SIGNAL: 0xD0,
109
+ SIGNAL_REQ: 0xD1,
110
+ SIGNAL_E2E: 0xD2,
111
+ SUBSCRIBE: 0xD3,
112
+ SUBSCRIBE_REQ: 0xD4,
113
+ UNSUBSCRIBE: 0xD5,
114
+ SERVER_SIGNAL: 0xD6,
115
+
116
+ // ..
117
+ IAM: 0xD9,
118
+ IAM_RES: 0xDA,
119
+
120
+ //..
121
+ SET: 0xDB, //
122
+ RESPONSE_CODE: 0xDC,
123
+ RESPONSE_MBP: 0xDD,
124
+
125
+ REQUEST: 0xDE, //client public
126
+ RESPONSE: 0xDF,
127
+ // ~DF
128
+
129
+
130
+ // F. Framing Flow control related framing protocol.(CongPacket)
131
+ FLOW_MODE: 0xF0,
132
+ WAIT: 0xF1,
133
+ RESUME: 0xF2,
134
+ //..
135
+ TIME_OUT: 0xFD,
136
+ OVER_SIZE: 0xFE,
137
+ OVER_FLOW: 0xFF
138
+
139
+ }
140
+
141
+ for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
142
+
143
+ // console.log( IOMsg );
144
+
145
+
146
+ export const API_TYPE = {
147
+ 'REQUEST_RESPONSE': 'requet_response',
148
+ 'ONE_WAY': 'one_way'
149
+ }
150
+
151
+
152
+
153
+ // api response status code
154
+ export const STATUS = {
155
+ OK: 0,
156
+ //0~127: success
157
+ //128~255: fail
158
+ ERROR: 255
159
+ }