demo/pong/link.c

See examples/demo/pong

/*
* ZentriOS SDK LICENSE AGREEMENT | Zentri.com, 2015.
*
* Use of source code and/or libraries contained in the ZentriOS SDK is
* subject to the Zentri Operating System SDK license agreement and
* applicable open source license agreements.
*
*/
#include "common.h"
/*************************************************************************************************/
zos_result_t link_init(void)
{
if(zn_load_app_settings("tcp_keepalive.ini") != ZOS_SUCCESS)
{
ZOS_LOG("Failed to load link settings");
}
game_context.socket_handle = -1;
return game_context.callback.link_start();
}
/*************************************************************************************************/
void link_deinit(void)
{
if(game_context.callback.link_stop != NULL)
{
game_context.callback.link_stop();
}
}
/*************************************************************************************************/
zos_result_t link_send_packet(link_packet_t *packet)
{
zos_result_t result;
packet->delimiter = PACKET_DELIMITER;
packet->checksum = get_packet_checksum(packet);
#ifndef SERVER_DEBUG_ENABLED
if(ZOS_FAILED(result, zn_tcp_write(game_context.socket_handle, packet, sizeof(link_packet_t), ZOS_FALSE)))
{
ZOS_LOG("Failed to send packet: %d", result);
}
#else
result = ZOS_SUCCESS;
#endif
return result;
}
/*************************************************************************************************/
void link_receive_packet(uint32_t handle)
{
for(;;)
{
zos_result_t result;
uint32_t bytes_read = 0;
// try to buffer more dta
const uint16_t available = RX_BUFFER_SIZE - game_context.rx_buffer.count;
uint8_t *ptr = &game_context.rx_buffer.buffer[game_context.rx_buffer.count];
if(available > 0)
{
if(ZOS_FAILED(result, zn_tcp_read(game_context.socket_handle, ptr, available, &bytes_read)))
{
ZOS_LOG("Failed read data: %d", result);
return;
}
// break out if there is no more data to be read
else if(bytes_read == 0)
{
//DEBUG_APP("no more data");
break;
}
}
// update the total bytes read count
game_context.rx_buffer.count += bytes_read;
// while there's at least one packet's worth of data buffered
while(game_context.rx_buffer.count >= sizeof(link_packet_t))
{
link_packet_t *packet = (link_packet_t*)game_context.rx_buffer.buffer;
// see if the delimiter is valid
if(packet->delimiter != PACKET_DELIMITER)
{
// it's not, shift all the data by one
--game_context.rx_buffer.count;
memmove(game_context.rx_buffer.buffer, game_context.rx_buffer.buffer+1, game_context.rx_buffer.count);
DEBUG_APP("bad delimiter");
continue;
}
// verify the checksum
const uint8_t checksum = get_packet_checksum(packet);
if(checksum != packet->checksum)
{
ZOS_LOG("Invalid checksum");
// it's not, shift all the data by one
--game_context.rx_buffer.count;
memmove(game_context.rx_buffer.buffer, game_context.rx_buffer.buffer+1, game_context.rx_buffer.count);
continue;
}
// we have a valid packet, process it
//DEBUG_APP("processing packet");
game_context.callback.game_process_packet(packet);
// remove it from the buffer
game_context.rx_buffer.count -= sizeof(link_packet_t);
memmove(game_context.rx_buffer.buffer, game_context.rx_buffer.buffer+sizeof(link_packet_t), game_context.rx_buffer.count);
}
}
}
/*************************************************************************************************/
static uint8_t get_packet_checksum(const link_packet_t *packet)
{
uint8_t checksum = 0;
const uint8_t *ptr = (const uint8_t*)packet;
for(uint8_t remaining = sizeof(link_packet_t)-1; remaining > 0; --remaining)
{
checksum += *ptr++;
}
return checksum;
}