TeamSpeak 3 SDK Connection problems - c++

I´m trying to use the TeamSpeak SDK for a personal project, but the code I wrote gives me weird errors.
I read the documentation many times to find an error but I can´t see why my program is not able to connect to the TeamSpeak Server.
Here is the output from the program:
Client library version: 3.0.3.2 [Build: 1433933257] SDK
Connection Status changed to: 1, errorNumber: 0
Connection Status changed to: 0, errorNumber: 1797
failed connection initialization
Here is the program code
#include <iostream>
#include <fstream>
#include <cstring>
#include <teamspeak/clientlib.h>
#include <teamspeak/public_errors.h>
uint64 connectionHandler;
void destroy();
void event_connectStatusChanged(uint64 serverConnectionIDHandler, int newStatus, unsigned int errorNumber);
void event_serverError(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage);
int main()
{
ClientUIFunctions uiFunctions;
memset(&uiFunctions, 0, sizeof(struct ClientUIFunctions));
uiFunctions.onConnectStatusChangeEvent = event_connectStatusChanged;
uiFunctions.onServerErrorEvent = event_serverError;
unsigned int error = ts3client_initClientLib(&uiFunctions, NULL, LogType_FILE, NULL, "./");
if (error != ERROR_ok)
printf("Error initializing clientlib: %i\n", error);
char* version;
error = ts3client_getClientLibVersion(&version);
if (error != ERROR_ok) {
printf("Error querying clientlib version: %d\n", error);
return 0;
}
printf("Client library version: %s\n", version); /* Print version */
ts3client_freeMemory(version); /* Release string */
if (ts3client_spawnNewServerConnectionHandler(0, &connectionHandler) != ERROR_ok)
{
destroy();
return 0;
}
char* identity;
ts3client_createIdentity(&identity);
error = ts3client_startConnection(connectionHandler, identity, "127.0.0.1", 9987, "test", NULL, "", "");
ts3client_freeMemory(identity);
if (error != ERROR_ok)
std::cout << "Connection failed!" << std::endl;
getchar();
ts3client_stopConnection(connectionHandler, "...");
destroy();
return 0;
}
void event_connectStatusChanged(uint64 serverConnectionIDHandler, int newStatus, unsigned int errorNumber)
{
printf("Connection Status changed to: %i, errorNumber: %i\n", newStatus, errorNumber);
if (errorNumber != ERROR_ok)
{
char* error;
ts3client_getErrorMessage(errorNumber, &error);
std::cout << error << std::endl;
ts3client_freeMemory(error);
}
}
void event_serverError(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage)
{
std::cout << "ERROR: " << errorMessage << std::endl << "Extra Message: " << extraMessage << std::endl;
}
void destroy()
{
ts3client_destroyServerConnectionHandler(connectionHandler);
ts3client_destroyClientLib();
}

It appears your client crashes immediately on connecting.
Here are some common causes to check:
Server doesn't exist at that address.
Server password is wrong.
Default channel doesn't exist.
Client has been banned.
Server is an illegal installation.
Security level of your identity is too low.
Also, this error can be triggered when a component such as client, server, etc need to be updated:
I updated to the latest version because the bot wouldn't launch and
figured I'd give the install on my other server another try. It's
working flawlessly now.
Ref: https://forum.sinusbot.com/threads/new-connection-status-0-error-1797.2508/

Related

Why "bad address" at ioctl() call

I recently develop a program to wrap CAN bus feature into a class so it will be more reusable in future. I try to separate codes from long-single-file into main, header and implementation files.
So I have 3 files, "canbus.cpp", "canbus.h" and "main.cpp". Here are my code snippet:
canbus.h
#ifndef CANBUS_H
#define CANBUS_H
#include ... (some includes go here)
class CANBUS{
int CANbusSocket = 0; // Canbus socket number which is gained at initiation process by linux socket() function call.
const char* CANbusInterfaceName;
int CANbusReadMode;
struct can_frame frame;
struct ifreq ifr;
struct sockaddr_can addr;
can_err_mask_t err_mask;
public:
// canbus mode mode: 0-listen only, 1-request pgn
// canbus interface name: "can0", "can1"
CANBUS(int mode=0, const char* name="can1");
int init();
};
#endif
canbus.cpp
#include "canbus.h"
#include <iostream>
// Constructor
CANBUS::CANBUS(int mode, const char* name){
CANbusReadMode = mode;
CANbusInterfaceName = name;
}
int CANBUS::init(){
CANbusSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if( CANbusSocket == -1){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error socket: %s\n", strerror( errno ));
}
strcpy(ifr.ifr_name, CANbusInterfaceName );
if(ioctl(CANbusSocket, SIOCGIFINDEX, ifr) != 0){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error ioctl: %s\n", strerror( errno ));
}
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(CANbusSocket, (struct sockaddr *)&addr, sizeof(addr)) !=0){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error bind: %s\n", strerror( errno ));
}
if(setsockopt(CANbusSocket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask))){ // enable error message frame
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error setsockopt: %s\n", strerror( errno ));
}
return 0;
}
main.cpp
#include "canbus.h"
#include <iostream>
int main(){
errno = 0;
const char* interfaceName = "can1";
int readMode = 0;
CANBUS can1(readMode, interfaceName);
can1.init();
// ... some codes here
return 0;
}
when I build with g++ and then run it, it will give error at ioctl() like this:
Error ioctl: Bad address
To note:
This kind program works previously which was written in the previous long-single-file code
Sequence in CANbus::init() is exactly the same order as previous code
variable for socket is now private while it was public in old
code
variable for socket is now accessed/assigned directly in CANbus::init() function while it was passed as pointer in previous CANbus::init(int* CANbusSocket) function
I've also tried to change CANbusSocket inside CANbus::init() from variable to pointer, but it gave me
Segmentation Fault

Mosquitto: Async connection on Raspberry PI 4 not working

I'm struggling using the mosquitto lib on my RaspberryPI 4 in an non-blocking way.
This is may main method:
#include <stdio.h>
#include <mosquitto.h>
#include "mqtt.h"
#include <string>
int main(int argc, char **argv)
{
printf("Start\n");
MqttConnector * mqtt = new MqttConnector("piClient", "send", "rc", 1883, "localhost", 60);
mqtt->startClient();
printf("MQTT is started\n");
while(1)
{
}
return 0;
}
Important parts of mqtt.cpp
#include "mqtt.h"
#include <stdio.h>
#include <string>
#include <string.h>
#include <mosquitto.h>
MqttConnector::MqttConnector(std::string id, std::string sendTopic, std::string receiveTopic, int port, std::string host, int keepalive)
{
mosquitto_lib_init();
mosqClient = mosquitto_new(id.c_str(), true, this);
if(!mosqClient){
fprintf(stderr, "Error: Out of memory.\n");
}
this->keepalive = keepalive;
this->id = id;
this->host = host;
this->port = port;
this->sendTopic = sendTopic;
this->receiveTopic = receiveTopic;
}
MqttConnector::~MqttConnector()
{
mosquitto_destroy(mosqClient);
mosquitto_lib_cleanup();
}
void MqttConnector::messageCallback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
//MqttConnector * mqttInstance = (MqttConnector *) userdata;
if(message->payloadlen){
std::string payloadString = reinterpret_cast<char*>(message->payload);
printf("Message arriving in %s : %s\n", message->topic, payloadString.c_str());
std::string rp = "rp";
if(payloadString == rp)
{
mosquitto_publish(mosq, NULL, "send", strlen("test"), "test", 2, false);
}
}else{
printf("Empty message arriving in %s\n", message->topic);
}
}
void MqttConnector::connectCallback(struct mosquitto *mosq, void *userdata, int result)
{
if(!result){
printf("Connection established\n");
}else{
fprintf(stderr, "Connect failed\n");
}
}
void MqttConnector::logCallback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("%s\n", str);
}
void MqttConnector::publishCallback(struct mosquitto *mosq, void *userdata, int usernumber)
{
printf("Published a message\n");
}
void MqttConnector::startClient()
{
mosquitto_message_callback_set(mosqClient, messageCallback);
mosquitto_log_callback_set(mosqClient, logCallback);
mosquitto_connect_callback_set(mosqClient, connectCallback);
mosquitto_publish_callback_set(mosqClient, publishCallback);
/*
//Connecting without async works! Publish and receiving messages work!
// loop starts by calling loop_forever
if(mosquitto_connect(mosqClient, host.c_str(), port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
}
mosquitto_subscribe(mosqClient, NULL, receiveTopic.c_str(), 2);
mosquitto_loop_forever(mosqClient, 10, 1);
*/
// According to docu we need to call loop_start instead of forever
// not able to publish/receive message with this!
if(mosquitto_connect_async(mosqClient, host.c_str(), port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
}
mosquitto_subscribe(mosqClient, NULL, receiveTopic.c_str(), 2);
mosquitto_loop_start(mosqClient);
}
Connecting to the server with mosquitto_connect and starting the loop with mosquitto_loop_forever is the blocking way. Therefore I only see the first print statement in the main.cpp ('Start'). But with this way, I'm able to publish and receive message with that client.
As soon as I connect with mosquitto_connect_async, I need to start the loop with mosquitto_loop_start as it is mentioned in the documentation. The client connects to the server without an error. And I also see the second print statement from the main.cpp now. But I'm not able to publish oder receive any messages with the mqtt client.
My first guess was that because of the threading, the messages are not printed on the console, but even other clients startet with mosquitto_sub don't receive a message from that c++ client.
Do I need to install something for threading support on the RPI4?
I don't understand why it is not working, because the RPI4 supports multithreading.
Thanks for helping

Mosquitto C++ Client on Raspberry PI not recieving messages

I'm trying to use mqtt on my raspberrpi4.
I installed mqtt and the c++ headers.
I start my broker with :
mosquitto -d
Then for a validation I start a client via the command line:
mosquitto_sub -d -t "test"
Then I also start the c++ client (following code):
#include <string.h>
#include <stdio.h>
#include <mosquitto.h>
char mqMsg[30];
void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
if(message->payloadlen){
printf("BANANA %s %s\n", message->topic, message->payload);
}else{
printf("BONONO %s (null)\n", message->topic);
}
fflush(stdout);
}
void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
int i;
if(!result){
mosquitto_publish(mosq, NULL, "hello/world", strlen(mqMsg), mqMsg, 2, 0);
}else{
fprintf(stderr, "Connect failed\n");
}
}
void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("%s\n", str);
}
void my_publish_callback(struct mosquitto *mosq, void *userdata, int usernumber)
{
/* We've published so lets exit nicely */
mosquitto_disconnect(mosq);
}
int main(int argc, char *argv[])
{
int i;
char *host = "localhost";
int port = 1883;
int keepalive = 60;
bool clean_session = true;
struct mosquitto *mosq = NULL;
sprintf(mqMsg,"%s",argv[1]);
printf("And the word is >> %s <<\n", mqMsg);
mosquitto_lib_init();
mosq = mosquitto_new(NULL, clean_session, NULL);
if(!mosq){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
mosquitto_log_callback_set(mosq, my_log_callback);
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_publish_callback_set(mosq, my_publish_callback);
if(mosquitto_connect(mosq, host, port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
return 1;
}
mosquitto_loop_forever(mosq, -1, 1);
mosquitto_subscribe(mosq, NULL, "test", 2);
while(1){
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
After that I publish something on the topic
mosquitto_pub -d -t "test" -m "test message"
I can see the message on the command line client but not on the c++ client?
Any idea why?
B.t.w. publishing via the c++ client works.
Thanks!
You call mosquitto_subscribe(mosq, NULL, "test", 2); after mosquitto_loop_forever(), therefore when your client actually runs, it's not subscribed to your topic. This also means that you don't need the while(1) in your code. See https://mosquitto.org/api/files/mosquitto-h.html#mosquitto_loop_forever for the description of the `mosquitto_loop_forever()' function.

How to use libssh's SCP with ssh::Session

I am using libssh's C++ wrapper (libsshpp.hpp) and I'm trying to call ssh_scp_new for an SCP routine by giving it my ssh::Session variable but I get the following error:
cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’ for argument ‘1’ to ‘ssh_scp_struct* ssh_scp_new(ssh_session, int, const char*)’
I am able to get SCP working by completely not using the C++ ssh::Session class and going with the C example but obviously this is not my preferred workaround. Looking at libsshpp.hpp I was able to find a getCSession() function but it is only privately accessible and I'm not sure how to use it (or if it's even what I think it is).
Here is my sample code:
#include <iostream>
#include <fstream>
#include <libssh/libsshpp.hpp>
int main()
{
int port = 22;
int verbosity = SSH_LOG_PROTOCOL;
ssh::Session session;
try
{
session.setOption(SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
session.setOption(SSH_OPTIONS_PORT, &port);
session.setOption(SSH_OPTIONS_USER, "user");
session.setOption(SSH_OPTIONS_HOST, "host");
session.connect();
if (session.isServerKnown() != SSH_SERVER_KNOWN_OK)
{
if (session.writeKnownhost() != SSH_OK)
{
std::cout << "writeKnownHost failed" << std::endl;
}
else
{
session.connect();
}
}
if (session.userauthPassword("password") !=
SSH_AUTH_SUCCESS)
{
std::cout << "Authentication Error" << std::endl;
}
ssh_scp scp;
int rc;
// error cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’
scp = ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
}
catch (ssh::SshException e)
{
std::cout << "Error during connection : ";
std::cout << e.getError() << std::endl;
}
return 0;
}
How do I SCP send or receive a file with libssh using C++ methods?
Thanks!
As you can see the error. You have to decide to weather use ssh::Session class or ssh_session structure. The libssh library is a C library, and it has just a C++ wrapper (that may not contain all functionalities like in the original language)
Here is how to send connect and send files using libssh library (current stable version 0.7.3) according to official documentation.
Using ssh_session: (in C)
-use ssh_new() to create a ssh_session pointer.
-use int ssh_connect(ssh_session session) to connect.
-use *int ssh_options_set ( ssh_session session, enum ssh_options_e type,const void * value )* Take a look on this documentation http://api.libssh.org/stable/group__libssh__session.html#ga7a801b85800baa3f4e16f5b47db0a73d
-add your controls
-send file using ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
-free the connection using ssh_free(ssh_session session)
//You can try this simple program (from official libssh tutorials)
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int scp_write(ssh_session session)
{
ssh_scp scp;
int rc;
scp = ssh_scp_new
(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
if (scp == NULL)
{
fprintf(stderr, "Error allocating scp session: %s\n", ssh_get_error(session));
return SSH_ERROR;
}
rc = ssh_scp_init(scp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
ssh_scp_free(scp);
return rc;
}
ssh_scp_close(scp);
ssh_scp_free(scp);
return SSH_OK;
}
int main(int argc, char* argv[])
ssh_session my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
return 1;
scp_write(my_ssh_session );
ssh_free(my_ssh_session);
return 0;
}
Using ssh::Session (in C++) well, no wrapper allows this currently :( .
Here is some useful examples for the use of libssh library. Hope it helps !
http://api.libssh.org/master/libssh_tutorial.html

Issues with converting a constant char array to an unsigned char pointer

I have been working on a project and boy oh boy does my head hurt on this one. I am using a networking library called "enet" and I am trying to assign the client who connects information. Using the tutorial on the site, I use: server.event.packet->data = "client info"; However, enet complains that the string is not an "unsigned char *". Here is the build log (using clang++ to compile):
./network.h:9:14: warning: in-class initialization of non-static data member accepted as a C++11 extension
[-Wc++11-extensions]
int clients = 0;
^
main.cpp:142:28: error: assigning to 'enet_uint8 *' (aka 'unsigned char *') from incompatible type
'const char [12]';
server.event.packet->data = "client info";
^ ~~~~~~~~~~~~~
I have tried every type of casting I can think of and that I have searched for, but nothing seems to work. I can't make the darn thing happy.
Main.cpp:
#include <iostream>
#include <string>
#include <sstream>
#include <istream>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <stdio.h>
#include "network.h"
#include "clients.h"
#include "config.h"
void runCommand(std::string command);
int startNetwork();
void shutdownNetwork();
void addClientRecord();
std::string getUsername();
std::string username;
bool manualInput = false;
bool debug = true;
int iPeerCount = 0;
Server server;
int main(int argc, char ** argv){
std::string currentCommand;
if(manualInput==true){
std::cout << "Please type a command: ";
std::getline(std::cin,currentCommand);
if(debug == true){
std::cout << currentCommand << std::endl;
}
runCommand(currentCommand);
}
startNetwork();
atexit(shutdownNetwork);
return 0;
}
int startNetwork(){
if (enet_initialize () != 0){
std::cout << "\nAn error has occured while initializing ENet.\n";
return EXIT_FAILURE;
}
server.startServer();
return 1;
}
void shutdownNetwork(){
enet_deinitialize();
}
int Server::startServer(){
// server.serverOne = enet_host_create (& server.address, 32, 2, 0, 0);
// if(CUSTOM_HOST == true){
// enet_address_set_host(&address, HOST);
// } else {
server.address.host = ENET_HOST_ANY;
// }
server.address.port = PORT;
server.serverOne = enet_host_create( & server.address, 32, 2, 0, 0);
if(debug==true){
printf("[NETWORK] Host: %x \n[NETWORK] Port: %u\n", server.address.host, address.port);
}
if(server.serverOne==NULL){
std::cout << "\nAn error has occured while starting the ENet server.\n";
exit (EXIT_FAILURE);
}
monitor();
return 1;
}
void Server::monitor(){
int clients = 0;
if(debug==true){
printf( "[NETWORK] Waiting for commands...\n" );
}
printf("[NETWORK] Server online, awaiting commands and/or connections...\n");
scan_network:
while(enet_host_service (serverOne, & event, 1000) > 0){
switch(event.type){
case ENET_EVENT_TYPE_CONNECT:
clients++;
printf("[INFO] New connection from: %x:%u.\n", event.peer -> address.host, event.peer -> address.port);
addClientRecord();
/* for(int x=0;x<32;x++){
if(clients[x].name != ""){ }
else{
clients[x].name = "full";
}
}*/
break;
case ENET_EVENT_TYPE_RECEIVE:
if(debug==true){ printf("A packet of length %lu containing %s was received from %s on channel %u.\n", event.packet -> dataLength, event.packet -> data, event.peer -> data, event.channelID); }
runCommand(reinterpret_cast<const char*>(event.packet -> data));
enet_packet_destroy(event.packet);
/* printf("Disconnect client %s ? ", event.peer -> data);
gets(buffer);
std::cout<<buffer<<std::endl;
if(buffer=="yes"){
enet_peer_disconnect(event.peer, 0);
}*/ //Do not use until fixed or spam!
break;
case ENET_EVENT_TYPE_DISCONNECT:
clients--;
printf("%s disconnected.\n", event.peer -> data);
event.peer -> data = NULL;
case ENET_EVENT_TYPE_NONE:
break;
}
}
goto scan_network;
}
void runCommand(std::string command){
if((command == "disconnect") || (command == "Disconnect") || (command=="DISCONNECT")){
enet_peer_disconnect(server.event.peer,0);
printf("[INFO] Client %s issued the disconnect command.\n", server.event.peer -> data);
}
}
std::string getUsername(){
return username;
}
void addClientRecord(){
std::string bufferName = ("client " + server.clients);
server.event.packet->data = "client info";
}
Network.h:
#include <enet/enet.h>
class Server {
public:
ENetAddress address;
ENetHost * serverOne;
ENetEvent event;
int clients = 0;
int startServer();
void monitor();
};
Any ideas and help is appreciated greatly. Cheers!
As far as I can see server is a struct of type Server, its field event is ENetEvent, and its field packet is of type _ENetPacket* and its field data is a unsigned char*. So now what is hapening: you create a сstring on the stack, then assign address of the first element to the data field of global object, then you leave the function and pointer is still alive while data stored there is no longer avaliable. That is why you get segfault when using correct typecast to unsigned char*.
So you should do the following:
void addClientRecord()
{
std::string bufferName = ("client " + server.clients);
char* clientName = "client info";
// Allocate mem
char* data = new unsigned char[strlen(clientName)];
// Copy string there
strcpy(data, clientName);
// Store pointer
server.event.packet->data = (unsigned char*)data;
}
and do no not forget to clear that allocated mem. That is for you should always check if server.event.packet->data contains non-nullptr value and if it does - delete and only then assign. And you should provide a destructor for Server where it will delete that string if any present and constructor to write there a nullptr on start so you won't delete some trash address, which most certainly will lead to crash. But first of all you need to figure out whether _ENetPacket or ENetEvent classes provide any functionality for data mentioned above. This is how cstrings work.
P.S. There should be a compiler flag that will toggle char to be unsigned by default.