1/* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "jerryscript-ext/debugger.h" 17#include "jext-common.h" 18 19#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) 20 21/* A simplified transmission layer. */ 22 23/** 24 * Size of the raw packet header. 25 */ 26#define JERRYX_DEBUGGER_RAWPACKET_HEADER_SIZE 1 27/** 28 * Maximum message size with 1 byte size field. 29 */ 30#define JERRYX_DEBUGGER_RAWPACKET_ONE_BYTE_LEN_MAX 255 31 32/** 33 * Header for incoming packets. 34 */ 35typedef struct 36{ 37 uint8_t size; /**< size of the message */ 38} jerryx_rawpacket_receive_header_t; 39 40/** 41 * Close a tcp connection. 42 */ 43static void 44jerryx_debugger_rp_close (jerry_debugger_transport_header_t *header_p) /**< header for the transport interface */ 45{ 46 JERRYX_ASSERT (!jerry_debugger_transport_is_connected ()); 47 48 jerry_heap_free ((void *) header_p, sizeof (jerry_debugger_transport_header_t)); 49} /* jerryx_debugger_rp_close */ 50 51/** 52 * Send data over a simple raw packet connection. 53 * 54 * @return true - if the data has been sent successfully 55 * false - otherwise 56 */ 57static bool 58jerryx_debugger_rp_send (jerry_debugger_transport_header_t *header_p, /**< header for the transport interface */ 59 uint8_t *message_p, /**< message to be sent */ 60 size_t message_length) /**< message length in bytes */ 61{ 62 JERRYX_ASSERT (message_length <= JERRYX_DEBUGGER_RAWPACKET_ONE_BYTE_LEN_MAX); 63 64 message_p[-1] = (uint8_t) message_length; 65 66 return header_p->next_p->send (header_p->next_p, message_p - 1, message_length + 1); 67} /* jerryx_debugger_rp_send */ 68 69/** 70 * Receive data from a rawpacket connection. 71 * 72 * @return true - if data has been received successfully 73 * false - otherwise 74 */ 75static bool 76jerryx_debugger_rp_receive (jerry_debugger_transport_header_t *header_p, /**< header for the transport interface */ 77 jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */ 78{ 79 if (!header_p->next_p->receive (header_p->next_p, receive_context_p)) 80 { 81 return false; 82 } 83 84 if (receive_context_p->message_p == NULL) 85 { 86 return true; 87 } 88 89 size_t message_total_length = receive_context_p->message_total_length; 90 91 if (message_total_length == 0) 92 { 93 /* Byte stream. */ 94 if (receive_context_p->message_length < sizeof (jerryx_rawpacket_receive_header_t)) 95 { 96 receive_context_p->message_p = NULL; 97 return true; 98 } 99 } 100 else 101 { 102 /* Datagram packet. */ 103 JERRYX_ASSERT (receive_context_p->message_length >= sizeof (jerryx_rawpacket_receive_header_t)); 104 } 105 106 uint8_t *message_p = receive_context_p->message_p; 107 size_t message_length = (size_t) (message_p[0]); 108 109 if (message_total_length == 0) 110 { 111 size_t new_total_length = message_length + sizeof (jerryx_rawpacket_receive_header_t); 112 113 /* Byte stream. */ 114 if (receive_context_p->message_length < new_total_length) 115 { 116 receive_context_p->message_p = NULL; 117 return true; 118 } 119 120 receive_context_p->message_total_length = new_total_length; 121 } 122 else 123 { 124 /* Datagram packet. */ 125 JERRYX_ASSERT (receive_context_p->message_length == (message_length + sizeof (jerryx_rawpacket_receive_header_t))); 126 } 127 128 receive_context_p->message_p = message_p + sizeof (jerryx_rawpacket_receive_header_t); 129 receive_context_p->message_length = message_length; 130 131 return true; 132} /* jerryx_debugger_rp_receive */ 133 134/** 135 * Initialize a simple raw packet transmission layer. 136 * 137 * @return true - if the connection succeeded 138 * false - otherwise 139 */ 140bool 141jerryx_debugger_rp_create (void) 142{ 143 const size_t interface_size = sizeof (jerry_debugger_transport_header_t); 144 jerry_debugger_transport_header_t *header_p; 145 header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (interface_size); 146 147 if (!header_p) 148 { 149 return false; 150 } 151 152 header_p->close = jerryx_debugger_rp_close; 153 header_p->send = jerryx_debugger_rp_send; 154 header_p->receive = jerryx_debugger_rp_receive; 155 156 jerry_debugger_transport_add (header_p, 157 JERRYX_DEBUGGER_RAWPACKET_HEADER_SIZE, 158 JERRYX_DEBUGGER_RAWPACKET_ONE_BYTE_LEN_MAX, 159 JERRYX_DEBUGGER_RAWPACKET_HEADER_SIZE, 160 JERRYX_DEBUGGER_RAWPACKET_ONE_BYTE_LEN_MAX); 161 162 return true; 163} /* jerryx_debugger_rp_create */ 164 165#else /* !(defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)) */ 166 167/** 168 * Dummy function when debugger is disabled. 169 * 170 * @return false 171 */ 172bool 173jerryx_debugger_rp_create (void) 174{ 175 return false; 176} /* jerryx_debugger_rp_create */ 177 178#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */ 179