/** * Handle a keepalive sent by the client * - check the crc * - send a keepalive back to the client * * @param data the connection packet * @param len the length of the connection packet * @param cli_addr the adress of the client * @param cli_len the length of cli_addr */ void handle_player_keepalive(char *data, unsigned int len, struct server *s) { struct player *pl; char *ptr = data; uint32_t pub_id, priv_id, ka_id; /* Check crc */ if(!packet_check_crc(data, len, 16)) return; /* Retrieve the player */ ptr += 4; priv_id = ru32(&ptr); pub_id = ru32(&ptr); ka_id = ru32(&ptr); /* Get the counter */ pl = get_player_by_ids(s, pub_id, priv_id); if (pl == NULL) { logger(LOG_WARN, "handle_player_keepalive : pl == NULL. Why????"); return; } /* Send the keepalive response */ s_resp_keepalive(pl, ka_id); /* Update the last_ping field */ gettimeofday(&pl->last_ping, NULL); }
/** * Handle a received audio packet by sending its audio * block to all the players in the same channel. * * @param in the received packet * @param len size of the received packet * * @return 0 on success, -1 on failure. */ int audio_received(char *in, size_t len, struct server *s) { uint32_t pub_id, priv_id; uint8_t data_codec; struct player *sender; struct channel *ch_in; struct player *tmp_pl; size_t data_size, audio_block_size, expected_size; ssize_t err; size_t iter; char *data, *ptr; data_codec = (uint8_t)in[3]; memcpy(&priv_id, in + 4, 4); memcpy(&pub_id, in + 8, 4); sender = get_player_by_ids(s, pub_id, priv_id); if (sender != NULL) { sender->stats->activ_time = time(NULL); /* update */ ch_in = sender->in_chan; /* Security checks */ if (data_codec != ch_in->codec) { printf("(EE) Player sent a wrong codec ID : %" PRIu8 ", expected : %" PRIu8 ".\n", data_codec, ch_in->codec); return -1; } audio_block_size = codec_offset[(int)data_codec] + codec_audio_size[(int)data_codec]; expected_size = 16 + audio_block_size; if (len != expected_size) { printf("(EE) Audio packet's size is incorrect : %zu bytes, expected : %zu.\n", len, expected_size); return -1; } /* Initialize the packet we want to send */ data_size = len + 6; /* we will add the id of player sending */ data = (char *)calloc(data_size, sizeof(char)); if (data == NULL) { printf("(WW) audio_received, could not allocate packet : %s.\n", strerror(errno)); return -1; } ptr = data; *(uint16_t *)ptr = 0xbef3; ptr += 2; /* function code */ /* 1 byte empty */ ptr += 1; /* NULL */ *(uint8_t *)ptr = ch_in->codec; ptr += 1; /* codec */ /* private ID */ ptr += 4; /* empty yet */ /* public ID */ ptr += 4; /* empty yet */ *(uint16_t *)ptr = *(uint16_t *)(in + 12); ptr += 2; /* counter */ *(uint16_t *)ptr = *(uint16_t *)(in + 14); ptr += 2; /* conversation counter */ *(uint32_t *)ptr = pub_id; ptr += 4; /* ID of sender */ ptr += 2; /* another counter?? */ memcpy(ptr, in + 16, audio_block_size); ptr += audio_block_size; ar_each(struct player *, tmp_pl, iter, ch_in->players) if (tmp_pl != sender) { *(uint32_t *)(data + 4) = tmp_pl->private_id; *(uint32_t *)(data + 8) = tmp_pl->public_id; err = send_to(sender->in_chan->in_server, data, data_size, 0, (struct sockaddr *)tmp_pl->cli_addr, tmp_pl->cli_len); if (err == -1) { printf("(WW) audio_received, could not send packet : %s.\n", strerror(errno)); } } ar_end_each; free(data); return 0; } else {