MySensors Library & Examples  2.3.2-62-ge298769
EthernetTCP.h
1 
2 /* EthernetTCP is a Strategy for the PJON framework (included in version v5.2)
3  It supports delivering PJON packets over Ethernet TCP.
4  Compliant with the PJON protocol layer specification v0.3
5  _____________________________________________________________________________
6 
7  EthernetTCP strategy and EthernetLink proposed and developed by Fred Larsen
8  02/10/2016
9 
10  Licensed under the Apache License, Version 2.0 (the "License");
11  you may not use this file except in compliance with the License.
12  You may obtain a copy of the License at
13 
14  http://www.apache.org/licenses/LICENSE-2.0
15 
16  Unless required by applicable law or agreed to in writing, software
17  distributed under the License is distributed on an "AS IS" BASIS,
18  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  See the License for the specific language governing permissions and
20  limitations under the License. */
21 
22 #pragma once
23 
24 #include "EthernetLink.h"
25 #include <PJONDefines.h>
26 
27 // Recommended receive time for this strategy, in microseconds
28 #ifndef ETCP_RECEIVE_TIME
29 #define ETCP_RECEIVE_TIME 0
30 #endif
31 
33 {
34 public:
35  EthernetLink link;
36  uint16_t last_send_result = PJON_FAIL;
37 
38  /* Caching incoming packet to enable byte for byte delivery */
39 
40  uint8_t *incoming_packet_buf_ptr = NULL;
41  uint16_t current_buffer_size = 0;
42  uint16_t incoming_packet_size = 0;
43 
44  static void static_receiver(
45  uint8_t id,
46  const uint8_t *payload,
47  uint16_t length,
48  void *callback_object
49  )
50  {
51  if(callback_object) {
52  ((EthernetTCP*)callback_object)->receiver(id, payload, length);
53  }
54  };
55 
56 
57  void receiver(uint8_t /*id*/, const uint8_t *payload, uint16_t length)
58  {
59  if(length <= current_buffer_size && incoming_packet_buf_ptr != NULL) {
60  memcpy(incoming_packet_buf_ptr, payload, length);
61  incoming_packet_size = length;
62  }
63  };
64 
65 
66  EthernetTCP()
67  {
68  link.set_receiver(static_receiver, this);
69 #ifdef _WIN32
70  // Initialize Winsock
71  WSAData wsaData;
72  WSAStartup(MAKEWORD(2, 2), &wsaData);
73 #endif
74  };
75 
76 #ifdef _WIN32
77  ~EthernetTCP()
78  {
79  // Cleanup Winsock
80  WSACleanup();
81  };
82 #endif
83 
84 
85  /* Returns the suggested delay related to the attempts passed as parameter: */
86 
87  uint32_t back_off(uint8_t attempts)
88  {
89  return 10000ul*attempts;
90  };
91 
92 
93  /* Begin method, to be called on initialization:
94  (returns always true) */
95 
96  bool begin(uint8_t /*did*/ = 0)
97  {
98  return true;
99  };
100 
101 
102  /* Check if the channel is free for transmission */
103 
104  bool can_start()
105  {
106  return link.device_id() != 0;
107  };
108 
109 
110  /* Returns the maximum number of attempts for each transmission: */
111 
112  static uint8_t get_max_attempts()
113  {
114  return 5;
115  };
116 
117 
118  /* Returns the recommended receive time for this strategy: */
119 
120  static uint16_t get_receive_time()
121  {
122  return ETCP_RECEIVE_TIME;
123  };
124 
125 
126  /* Handle a collision (empty because handled on Ethernet level): */
127 
128  void handle_collision() { };
129 
130 
131  /* Receive a frame: */
132 
133  uint16_t receive_frame(uint8_t *data, uint16_t max_length)
134  {
135  // Register supplied buffer as target for EthernetLink callback function
136  incoming_packet_buf_ptr = data;
137  current_buffer_size = max_length;
138  incoming_packet_size = 0;
139 
140  // Receive a packet
141  uint16_t result = link.receive();
142 
143  // Forget about buffer and return result size
144  uint16_t received_packet_size = incoming_packet_size;
145  incoming_packet_buf_ptr = NULL;
146  incoming_packet_size = 0;
147 
148  return result == PJON_ACK ? received_packet_size : PJON_FAIL;
149  }
150 
151 
152  /* Receive byte response */
153 
154  uint16_t receive_response()
155  {
156  return last_send_result;
157  };
158 
159 
160  /* Send byte response to package transmitter */
161 
162  void send_response(uint8_t /*response*/) // Empty, ACK is always sent
163  {
164  };
165 
166 
167  /* Send a frame: */
168 
169  void send_frame(uint8_t *data, uint16_t length)
170  {
171  if(length > 0)
172  last_send_result =
173  link.send((uint8_t)data[0], (const uint8_t*)data, length);
174  };
175 };
data
char data[MAX_PAYLOAD_SIZE+1]
Buffer for raw payload data.
Definition: MyMessage.h:654
EthernetTCP
Definition: EthernetTCP.h:32