Live555 (RTP/RTSP) on armv7s - c++

it is possible to use live555 lib with armv7s? Becasue I try to compile it with config
# Change the following version number, if necessary, before running "genMakefiles iphoneos"
IOS_VERSION = 7.0
DEVELOPER_PATH = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
TOOL_PATH = $(DEVELOPER_PATH)/usr/bin
SDK_PATH = $(DEVELOPER_PATH)/SDKs
SDK = $(SDK_PATH)/iPhoneOS$(IOS_VERSION).sdk
COMPILE_OPTS = $(INCLUDES) -I. $(EXTRA_LDFLAGS) -DBSD=1 -O2 -DSOCKLEN_T=socklen_t -DHAVE_SOCKADDR_LEN=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -fPIC -arch armv7s --sysroot=$(SDK)
C = c
C_COMPILER = $(TOOL_PATH)/gcc
C_FLAGS = $(COMPILE_OPTS)
CPP = cpp
CPLUSPLUS_COMPILER = $(TOOL_PATH)/g++
CPLUSPLUS_FLAGS = $(COMPILE_OPTS) -Wall
OBJ = o
LINK = $(TOOL_PATH)/g++ -o
LINK_OPTS = -L. -arch armv7s --sysroot=$(SDK) -L$(SDK)/usr/lib/system
CONSOLE_LINK_OPTS = $(LINK_OPTS)
LIBRARY_LINK = libtool -s -o
LIBRARY_LINK_OPTS =
LIB_SUFFIX = a
LIBS_FOR_CONSOLE_APPLICATION =
LIBS_FOR_GUI_APPLICATION =
EXE =
then I try copy&paste program testMP3Reciver to my iOS project (yes I use .mm as postfix instead of .m, and include every header is needed), but still I got 14 errors Undefinded symbols for architecture armv7s
My code:
#import "TViewController.h"
#include "liveMedia.hh"
#include "GroupsockHelper.hh"
#include "BasicUsageEnvironment.hh"
#interface TViewController ()
#end
#implementation TViewController
UsageEnvironment* env;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
struct sessionState_t {
FramedSource* source;
FileSink* sink;
RTCPInstance* rtcpInstance;
} sessionState;
- (IBAction)start:(id)sender {
if (!wasClicked) {
//start
[self startButton];
wasClicked = true;
} else {
//stop
[self stopButton];
wasClicked = false;
}
}
-(void)startButton{
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
// Create the data sink for 'stdout':
sessionState.sink = FileSink::createNew(*env, "stdout");
// Note: The string "stdout" is handled as a special case.
// A real file name could have been used instead.
// Create 'groupsocks' for RTP and RTCP:
char const* sessionAddressStr
#ifdef USE_SSM
= "232.255.42.42";
#else
= "239.255.42.42";
// Note: If the session is unicast rather than multicast,
// then replace this string with "0.0.0.0"
#endif
const unsigned short rtpPortNum = 6666;
const unsigned short rtcpPortNum = rtpPortNum+1;
#ifndef USE_SSM
const unsigned char ttl = 1; // low, in case routers don't admin scope
#endif
struct in_addr sessionAddress;
sessionAddress.s_addr = our_inet_addr(sessionAddressStr);
const Port rtpPort(rtpPortNum);
const Port rtcpPort(rtcpPortNum);
#ifdef USE_SSM
char* sourceAddressStr = "aaa.bbb.ccc.ddd";
// replace this with the real source address
struct in_addr sourceFilterAddress;
sourceFilterAddress.s_addr = our_inet_addr(sourceAddressStr);
Groupsock rtpGroupsock(*env, sessionAddress, sourceFilterAddress, rtpPort);
Groupsock rtcpGroupsock(*env, sessionAddress, sourceFilterAddress, rtcpPort);
rtcpGroupsock.changeDestinationParameters(sourceFilterAddress,0,~0);
// our RTCP "RR"s are sent back using unicast
#else
Groupsock rtpGroupsock(*env, sessionAddress, rtpPort, ttl);
Groupsock rtcpGroupsock(*env, sessionAddress, rtcpPort, ttl);
#endif
RTPSource* rtpSource;
#ifndef STREAM_USING_ADUS
// Create the data source: a "MPEG Audio RTP source"
rtpSource = MPEG1or2AudioRTPSource::createNew(*env, &rtpGroupsock);
#else
// Create the data source: a "MP3 *ADU* RTP source"
unsigned char rtpPayloadFormat = 96; // a dynamic payload type
rtpSource
= MP3ADURTPSource::createNew(*env, &rtpGroupsock, rtpPayloadFormat);
#endif
// Create (and start) a 'RTCP instance' for the RTP source:
const unsigned estimatedSessionBandwidth = 160; // in kbps; for RTCP b/w share
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char*)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = '\0'; // just in case
sessionState.rtcpInstance
= RTCPInstance::createNew(*env, &rtcpGroupsock,
estimatedSessionBandwidth, CNAME,
NULL /* we're a client */, rtpSource);
// Note: This starts RTCP running automatically
sessionState.source = rtpSource;
#ifdef STREAM_USING_ADUS
// Add a filter that deinterleaves the ADUs after depacketizing them:
sessionState.source
= MP3ADUdeinterleaver::createNew(*env, sessionState.source);
if (sessionState.source == NULL) {
*env << "Unable to create an ADU deinterleaving filter for the source\n";
exit(1);
}
// Add another filter that converts these ADUs to MP3s:
sessionState.source
= MP3FromADUSource::createNew(*env, sessionState.source);
if (sessionState.source == NULL) {
*env << "Unable to create an ADU->MP3 filter for the source\n";
exit(1);
}
#endif
// Finally, start receiving the multicast stream:
*env << "Beginning receiving multicast stream...\n";
sessionState.sink->startPlaying(*sessionState.source, afterPlaying, NULL);
env->taskScheduler().doEventLoop(); // does not return
}
void afterPlaying(void* /*clientData*/) {
*env << "...done receiving\n";
// End by closing the media:
Medium::close(sessionState.rtcpInstance); // Note: Sends a RTCP BYE
Medium::close(sessionState.sink);
Medium::close(sessionState.source);
}
-(void)stopButton{
afterPlaying;
}
#end
So I ask again, it's even posible to use live555 on armv7s? Maybe I should use another lib?
Solution/Update
I have to throw away armv7s, instead of it I use this project to create fat lib for iOS.
Step-by-step solution:
Clone this project git clone git#github.com:weevilgenius/live555-ios.git
Build lib, and copy to your project. At start I was have problem with finding compiled lib. So for those who don't know how to find it. After building lib in Xcode file tree open folder Products and right-click on libLive555.a then select "Show in Finder".
Add to your project every .hh. Those files are in folder include in every subfolder of folder Live555. Now everything should be just fine :)

Related

I was running a ns3 simulation and i get this reference error

I am not much similar with c++ sourcecode files.I tried my best looking into the error and navigating through references could not find anything looked in the methods and everything, may be i did left something out...I dont know.
So, I was trying to simulate the concept called congestion control through Network simulator (NS3) with the file "seventh.cc".
actually it may look different but the error was a reference error and related to the cpp concepts. Down below are the files...
Seventh.cc
#include "tutorial-app.h"
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/stats-module.h"
#include <fstream>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("SeventhScriptExample");
// ===========================================================================
//
// node 0 node 1
// +----------------+ +----------------+
// | ns-3 TCP | | ns-3 TCP |
// +----------------+ +----------------+
// | 10.1.1.1 | | 10.1.1.2 |
// +----------------+ +----------------+
// | point-to-point | | point-to-point |
// +----------------+ +----------------+
// | |
// +---------------------+
// 5 Mbps, 2 ms
//
//
// We want to look at changes in the ns-3 TCP congestion window. We need
// to crank up a flow and hook the CongestionWindow attribute on the socket
// of the sender. Normally one would use an on-off application to generate a
// flow, but this has a couple of problems. First, the socket of the on-off
// application is not created until Application Start time, so we wouldn't be
// able to hook the socket (now) at configuration time. Second, even if we
// could arrange a call after start time, the socket is not public so we
// couldn't get at it.
//
// So, we can cook up a simple version of the on-off application that does what
// we want. On the plus side we don't need all of the complexity of the on-off
// application. On the minus side, we don't have a helper, so we have to get
// a little more involved in the details, but this is trivial.
//
// So first, we create a socket and do the trace connect on it; then we pass
// this socket into the constructor of our simple application which we then
// install in the source node.
//
// NOTE: If this example gets modified, do not forget to update the .png figure
// in src/stats/docs/seventh-packet-byte-count.png
// ===========================================================================
//
/**
* Congestion window change callback
*
* \param stream The ouput stream file.
* \param oldCwnd Old congestion window.
* \param newCwnd New congestion window.
*/
static void
CwndChange(Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "\t" << newCwnd);
*stream->GetStream() << Simulator::Now().GetSeconds() << "\t" << oldCwnd << "\t" << newCwnd
<< std::endl;
}
/**
* Rx drop callback
*
* \param file The ouput PCAP file.
* \param p The dropped packet.
*/
static void
RxDrop(Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
{
NS_LOG_UNCOND("RxDrop at " << Simulator::Now().GetSeconds());
file->Write(Simulator::Now(), p);
}
int
main(int argc, char* argv[])
{
bool useV6 = false;
CommandLine cmd(__FILE__);
cmd.AddValue("useIpv6", "Use Ipv6", useV6);
cmd.Parse(argc, argv);
NodeContainer nodes;
nodes.Create(2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));
NetDeviceContainer devices;
devices = pointToPoint.Install(nodes);
Ptr<RateErrorModel> em = CreateObject<RateErrorModel>();
em->SetAttribute("ErrorRate", DoubleValue(0.00001));
devices.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(em));
InternetStackHelper stack;
stack.Install(nodes);
uint16_t sinkPort = 8080;
Address sinkAddress;
Address anyAddress;
std::string probeType;
std::string tracePath;
if (useV6 == false)
{
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign(devices);
sinkAddress = InetSocketAddress(interfaces.GetAddress(1), sinkPort);
anyAddress = InetSocketAddress(Ipv4Address::GetAny(), sinkPort);
probeType = "ns3::Ipv4PacketProbe";
tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
}
else
{
Ipv6AddressHelper address;
address.SetBase("2001:0000:f00d:cafe::", Ipv6Prefix(64));
Ipv6InterfaceContainer interfaces = address.Assign(devices);
sinkAddress = Inet6SocketAddress(interfaces.GetAddress(1, 1), sinkPort);
anyAddress = Inet6SocketAddress(Ipv6Address::GetAny(), sinkPort);
probeType = "ns3::Ipv6PacketProbe";
tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
}
PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", anyAddress);
ApplicationContainer sinkApps = packetSinkHelper.Install(nodes.Get(1));
sinkApps.Start(Seconds(0.));
sinkApps.Stop(Seconds(20.));
Ptr<Socket> ns3TcpSocket = Socket::CreateSocket(nodes.Get(0), TcpSocketFactory::GetTypeId());
Ptr<TutorialApp> app = CreateObject<TutorialApp>();
app->Setup(ns3TcpSocket, sinkAddress, 1040, 1000, DataRate("1Mbps"));
nodes.Get(0)->AddApplication(app);
app->SetStartTime(Seconds(1.));
app->SetStopTime(Seconds(20.));
AsciiTraceHelper asciiTraceHelper;
Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream("seventh.cwnd");
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow",
MakeBoundCallback(&CwndChange, stream));
PcapHelper pcapHelper;
Ptr<PcapFileWrapper> file =
pcapHelper.CreateFile("seventh.pcap", std::ios::out, PcapHelper::DLT_PPP);
devices.Get(1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback(&RxDrop, file));
// Use GnuplotHelper to plot the packet byte count over time
GnuplotHelper plotHelper;
// Configure the plot. The first argument is the file name prefix
// for the output files generated. The second, third, and fourth
// arguments are, respectively, the plot title, x-axis, and y-axis labels
plotHelper.ConfigurePlot("seventh-packet-byte-count",
"Packet Byte Count vs. Time",
"Time (Seconds)",
"Packet Byte Count");
// Specify the probe type, trace source path (in configuration namespace), and
// probe output trace source ("OutputBytes") to plot. The fourth argument
// specifies the name of the data series label on the plot. The last
// argument formats the plot by specifying where the key should be placed.
plotHelper.PlotProbe(probeType,
tracePath,
"OutputBytes",
"Packet Byte Count",
GnuplotAggregator::KEY_BELOW);
// Use FileHelper to write out the packet byte count over time
FileHelper fileHelper;
// Configure the file to be written, and the formatting of output data.
fileHelper.ConfigureFile("seventh-packet-byte-count", FileAggregator::FORMATTED);
// Set the labels for this formatted output file.
fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");
// Specify the probe type, trace source path (in configuration namespace), and
// probe output trace source ("OutputBytes") to write.
fileHelper.WriteProbe(probeType, tracePath, "OutputBytes");
Simulator::Stop(Seconds(20));
Simulator::Run();
Simulator::Destroy();
return 0;
}
Here is the error on commandpromt:
/usr/bin/ld: CMakeFiles/scratch_seventh.dir/seventh.cc.o: in function `ns3::Ptr<ns3::TutorialApp> ns3::CreateObject<ns3::TutorialApp>()':
/mnt/f/OneDrive/Desktop/likhitha/repos/ns-allinone-3.37/ns-3.37/src/core/model/object.h:581: undefined reference to `ns3::TutorialApp::TutorialApp()'
/usr/bin/ld: CMakeFiles/scratch_seventh.dir/seventh.cc.o: in function `ns3::Ptr<ns3::TutorialApp> ns3::CompleteConstruct<ns3::TutorialApp>(ns3::TutorialApp*)':
/mnt/f/OneDrive/Desktop/likhitha/repos/ns-allinone-3.37/ns-3.37/src/core/model/object.h:561: undefined reference to `ns3::TutorialApp::GetTypeId()'
/usr/bin/ld: CMakeFiles/scratch_seventh.dir/seventh.cc.o: in function `main':
/mnt/f/OneDrive/Desktop/likhitha/repos/ns-allinone-3.37/ns-3.37/scratch/seventh.cc:157: undefined reference to `ns3::TutorialApp::Setup(ns3::Ptr<ns3::Socket>, ns3::Address, unsigned int, unsigned int, ns3::DataRate)'
collect2: error: ld returned 1 exit status
gmake[3]: *** [scratch/CMakeFiles/scratch_seventh.dir/build.make:103: ../build/scratch/ns3.37-seventh-default] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:17305: scratch/CMakeFiles/scratch_seventh.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:17311: scratch/CMakeFiles/scratch_seventh.dir/rule] Error 2
gmake: *** [Makefile:5913: scratch_seventh] Error 2
the code for the headerfile tutorial-app.h and also the source file tutorial-app.cc
tutorial-app.h
#ifndef TUTORIAL_APP_H
#define TUTORIAL_APP_H
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
namespace ns3
{
class Application;
/**
* Tutorial - a simple Application sending packets.
*/
class TutorialApp : public Application
{
public:
TutorialApp();
~TutorialApp() override;
/**
* Register this type.
* \return The TypeId.
*/
static TypeId GetTypeId();
/**
* Setup the socket.
* \param socket The socket.
* \param address The destination address.
* \param packetSize The packet size to transmit.
* \param nPackets The number of packets to transmit.
* \param dataRate the datarate to use.
*/
void Setup(Ptr<Socket> socket,
Address address,
uint32_t packetSize,
uint32_t nPackets,
DataRate dataRate);
private:
void StartApplication() override;
void StopApplication() override;
/// Schedule a new transmission.
void ScheduleTx();
/// Send a packet.
void SendPacket();
Ptr<Socket> m_socket; //!< The tranmission socket.
Address m_peer; //!< The destination address.
uint32_t m_packetSize; //!< The packet size.
uint32_t m_nPackets; //!< The number of pacts to send.
DataRate m_dataRate; //!< The datarate to use.
EventId m_sendEvent; //!< Send event.
bool m_running; //!< True if the application is running.
uint32_t m_packetsSent; //!< The number of pacts sent.
};
} // namespace ns3
#endif /* TUTORIAL_APP_H */
/////////////////////////////////////////////////////////////////////////////////////
tutorial-app.cc
#include "tutorial-app.h"
#include "ns3/applications-module.h"
using namespace ns3;
TutorialApp::TutorialApp()
: m_socket(nullptr),
m_peer(),
m_packetSize(0),
m_nPackets(0),
m_dataRate(0),
m_sendEvent(),
m_running(false),
m_packetsSent(0)
{
}
TutorialApp::~TutorialApp()
{
m_socket = nullptr;
}
/* static */
TypeId
TutorialApp::GetTypeId()
{
static TypeId tid = TypeId("TutorialApp")
.SetParent<Application>()
.SetGroupName("Tutorial")
.AddConstructor<TutorialApp>();
return tid;
}
void
TutorialApp::Setup(Ptr<Socket> socket,
Address address,
uint32_t packetSize,
uint32_t nPackets,
DataRate dataRate)
{
m_socket = socket;
m_peer = address;
m_packetSize = packetSize;
m_nPackets = nPackets;
m_dataRate = dataRate;
}
void
TutorialApp::StartApplication()
{
m_running = true;
m_packetsSent = 0;
m_socket->Bind();
m_socket->Connect(m_peer);
SendPacket();
}
void
TutorialApp::StopApplication()
{
m_running = false;
if (m_sendEvent.IsRunning())
{
Simulator::Cancel(m_sendEvent);
}
if (m_socket)
{
m_socket->Close();
}
}
void
TutorialApp::SendPacket()
{
Ptr<Packet> packet = Create<Packet>(m_packetSize);
m_socket->Send(packet);
if (++m_packetsSent < m_nPackets)
{
ScheduleTx();
}
}
void
TutorialApp::ScheduleTx()
{
if (m_running)
{
Time tNext(Seconds(m_packetSize * 8 / static_cast<double>(m_dataRate.GetBitRate())));
m_sendEvent = Simulator::Schedule(tNext, &TutorialApp::SendPacket, this);
}
}
Here is the cmakelists file:
set(target_prefix scratch_)
function(create_scratch source_files)
# Return early if no sources in the subdirectory
list(LENGTH source_files number_sources)
if(number_sources EQUAL 0)
return()
endif()
# If the scratch has more than a source file, we need to find the source with
# the main function
set(scratch_src)
foreach(source_file ${source_files})
file(READ ${source_file} source_file_contents)
string(REGEX MATCHALL "main[(| (]" main_position "${source_file_contents}")
if(CMAKE_MATCH_0)
set(scratch_src ${source_file})
endif()
endforeach()
if(NOT scratch_src)
return()
endif()
# Get parent directory name
get_filename_component(scratch_dirname ${scratch_src} DIRECTORY)
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" scratch_dirname
"${scratch_dirname}"
)
string(REPLACE "/" "_" scratch_dirname "${scratch_dirname}")
# Get source name
get_filename_component(scratch_name ${scratch_src} NAME_WE)
set(target_prefix scratch_)
if(scratch_dirname)
# Join the names together if dirname is not the scratch folder
set(target_prefix scratch${scratch_dirname}_)
endif()
# Get source absolute path and transform into relative path
get_filename_component(scratch_src ${scratch_src} ABSOLUTE)
get_filename_component(scratch_absolute_directory ${scratch_src} DIRECTORY)
string(REPLACE "${PROJECT_SOURCE_DIR}" "${CMAKE_OUTPUT_DIRECTORY}"
scratch_directory ${scratch_absolute_directory}
)
build_exec(
EXECNAME ${scratch_name}
EXECNAME_PREFIX ${target_prefix}
SOURCE_FILES "${source_files}"
LIBRARIES_TO_LINK "${ns3-libs}" "${ns3-contrib-libs}"
EXECUTABLE_DIRECTORY_PATH ${scratch_directory}/
)
endfunction()
# Scan *.cc files in ns-3-dev/scratch and build a target for each
file(GLOB single_source_file_scratches CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/[^.]*.cc)
foreach(scratch_src ${single_source_file_scratches})
create_scratch(${scratch_src})
endforeach()
# Scan *.cc files in ns-3-dev/scratch subdirectories and build a target for each
# subdirectory
file(
GLOB_RECURSE scratch_subdirectories
CONFIGURE_DEPENDS
LIST_DIRECTORIES true
${CMAKE_CURRENT_SOURCE_DIR}/**
)
# Filter out files
foreach(entry ${scratch_subdirectories})
if(NOT (IS_DIRECTORY ${entry}))
list(REMOVE_ITEM scratch_subdirectories ${entry})
endif()
endforeach()
foreach(subdir ${scratch_subdirectories})
if(EXISTS ${subdir}/CMakeLists.txt)
# If the subdirectory contains a CMakeLists.txt file
# we let the CMake file manage the source files
#
# Use this if you want to link to external libraries
# without creating a module
add_subdirectory(${subdir})
else()
# Otherwise we pick all the files in the subdirectory
# and create a scratch for them automatically
file(GLOB scratch_sources CONFIGURE_DEPENDS ${subdir}/[^.]*.cc)
create_scratch("${scratch_sources}")
endif()
endforeach()
I has some assumptions but the code was given by the network simulator module,thought should not be modify any thing unless i am sure and asking u guys.
It was for my academic lab, i was already one day behind schedule stuck with building the ns3 packages for 2days straight, please help me out. thanks in advance.

Windows Sharing file over network NetShareAdd Error 53

I tried to compile this example from microsoft docs for sharing a folder over network however the executable gives an error.
Full Code :
#include "stdafx.h"
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include <lm.h>
#pragma comment(lib, "Netapi32.lib")
void wmain(int argc, TCHAR *argv[])
{
NET_API_STATUS res;
SHARE_INFO_2 p;
DWORD parm_err = 0;
if (argc<2)
printf("Usage: NetShareAdd server\n");
else
{
//
// Fill in the SHARE_INFO_2 structure.
//
p.shi2_netname = TEXT("TESTSHARE");
p.shi2_type = STYPE_DISKTREE; // disk drive
p.shi2_remark = TEXT("TESTSHARE to test NetShareAdd");
p.shi2_permissions = 0;
p.shi2_max_uses = 4;
p.shi2_current_uses = 0;
p.shi2_path = TEXT("F:\\abc");
p.shi2_passwd = NULL; // no password
//
// Call the NetShareAdd function,
// specifying level 2.
//
res = NetShareAdd(argv[1], 2, (LPBYTE)&p, &parm_err);
//
// If the call succeeds, inform the user.
//
if (res == 0)
printf("Share created.\n");
// Otherwise, print an error,
// and identify the parameter in error.
//
else
printf("Error: %u\tparmerr=%u\n", res, parm_err);
}
return;
}
Exe command :
ConsoleApplication1.exe myShare
Error Shown :
Error: 53 parmerr=0
However the follwing from cmd works fine :
net share abc=F:\abc
I am unable to figure out what actually the error is and how to resolve that. can anybody help?
I am on windows 11 and code is compiled on VS 2015 Community.
With admin privileges, servername ConsoleApplication1.exe localhost and ConsoleApplication1.exe 127.0.0.1 worked fine.

undefined symbol error when loading a module, using AWS C++ SDK, in Freeswitch

I am asking this question again as the mods decided to close my question here as a duplicate, within minutes of it being asked (and also down-voted!!). Now I have gone through all 33 answers of what was thought to be an answer to my solution, but it didn't help. So I am asking again.
I am trying to build a FreeSWITCH module to add text-to-speech functionality using AWS Polly & the AWS C++ SDK.
Dev environment is Debian 8, g++ 4.9.2. AWS C++ SDK is built using instructions here except that I turned off shared libs (produces .a lib files).
The AWS C++ SDK was built as recommended here (basically C++ code with C++ linkage). mod_polly.cpp is built with C++ linkage as well to produce mod_polly.so. It does refer to some C headers & functions. This was built as -
g++ -shared -o mod_polly.so -L/usr/local/lib/ -laws-cpp-sdk-polly -laws-cpp-sdk-core -fPIC -g -ggdb -std=c++11 -Wall -Werror -I/usr/src/freeswitch/src/include/ -I/usr/src/freeswitch/libs/libteletone/src/ mod_polly.cpp
Source below -
extern "C" {
#include <switch.h>
}
#include <fstream>
#define BIG_ENDIAN_SYSTEM (*(uint16_t *)"\0\xff" < 0x100)
#define REVERSE_BYTES(...) do for(size_t REVERSE_BYTES=0; REVERSE_BYTES<sizeof(__VA_ARGS__)>>1; ++REVERSE_BYTES)\
((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES],\
((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES],\
((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES];\
while(0)
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/core/utils/Outcome.h>
#include <aws/polly/PollyClient.h>
#include <aws/polly/model/SynthesizeSpeechRequest.h>
#include <aws/polly/model/SynthesizeSpeechResult.h>
#include <aws/polly/model/TextType.h>
#include <aws/polly/model/LanguageCode.h>
#include <aws/polly/model/OutputFormat.h>
#include <aws/polly/model/VoiceId.h>
typedef unsigned long DWORD; // 32-bit unsigned integer
typedef unsigned short WORD; // 16-bit unsigned integer
struct riff // Data Bytes Total
{
char chunkID[4]; // "RIFF" 4 4
DWORD riffSize; // file size - 8 4 8
char typeID[4]; // "WAVE" 4 12
char formatChunkID[4]; // "fmt " 4 16
DWORD formatChunkSize; // 16 bytes 4 20
WORD formatTag; // 2 22
WORD noOfChannels; // 2 24
DWORD samplesPerSec; // 4 28
DWORD bytesPerSec; // 4 32
WORD blockAlign; // 2 34
WORD bitsPerSample; // 2 36
char dataChunkID[4]; // "data" 4 40
DWORD dataChunkSize; // not fixed 4 44
};
static struct {
switch_mutex_t *mutex;
switch_thread_rwlock_t *running_rwlock;
switch_memory_pool_t *pool;
int running;
} process;
static struct {
Aws::Auth::AWSCredentials *credentials;
Aws::Client::ClientConfiguration *config;
Aws::SDKOptions *options;
} globals;
switch_loadable_module_interface_t *MODULE_INTERFACE;
static char *supported_formats[SWITCH_MAX_CODECS] = { 0 };
/* Prototypes */
SWITCH_MODULE_LOAD_FUNCTION(mod_polly_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_polly_shutdown);
SWITCH_MODULE_DEFINITION(mod_polly, mod_polly_load, mod_polly_shutdown, NULL);
// ------------------------------------------------------------------------------------------------------------------
/* Implementation */
std::ostream& operator<<(std::ostream& out, const riff& h)
{
if BIG_ENDIAN_SYSTEM {
struct riff hdr = std::move(h);
REVERSE_BYTES(hdr.riffSize);
REVERSE_BYTES(hdr.formatChunkSize);
REVERSE_BYTES(hdr.formatTag);
REVERSE_BYTES(hdr.noOfChannels);
REVERSE_BYTES(hdr.samplesPerSec);
REVERSE_BYTES(hdr.bytesPerSec);
REVERSE_BYTES(hdr.blockAlign);
REVERSE_BYTES(hdr.bitsPerSample);
REVERSE_BYTES(hdr.dataChunkSize);
return out
.write(hdr.chunkID, 4)
.write((const char *)&hdr.riffSize, 4)
.write(hdr.typeID, 4)
.write(hdr.formatChunkID, 4)
.write((const char *)&hdr.formatChunkSize, 4)
.write((const char *)&hdr.formatTag, 2)
.write((const char *)&hdr.noOfChannels, 2)
.write((const char *)&hdr.samplesPerSec, 4)
.write((const char *)&hdr.bytesPerSec, 4)
.write((const char *)&hdr.blockAlign, 2)
.write((const char *)&hdr.bitsPerSample, 2)
.write(hdr.dataChunkID, 4)
.write((const char *)&hdr.dataChunkSize, 4);
} else {
return out
.write(h.chunkID, 4)
.write((const char *)&h.riffSize, 4)
.write(h.typeID, 4)
.write(h.formatChunkID, 4)
.write((const char *)&h.formatChunkSize, 4)
.write((const char *)&h.formatTag, 2)
.write((const char *)&h.noOfChannels, 2)
.write((const char *)&h.samplesPerSec, 4)
.write((const char *)&h.bytesPerSec, 4)
.write((const char *)&h.blockAlign, 2)
.write((const char *)&h.bitsPerSample, 2)
.write(h.dataChunkID, 4)
.write((const char *)&h.dataChunkSize, 4);
}
}
riff init_pcm_header(std::ostream& in)
{
// get length of file
in.seekp(0, in.end);
DWORD sz = in.tellp();
in.seekp(0, in.beg);
struct riff result = {
{'R','I','F','F'}, // chunkID
sz + 0x24, // riffSize (size of stream + 0x24) or (file size - 8)
{'W','A','V','E'}, // typeID
{'f','m','t',' '}, // formatChunkID
16, // formatChunkSize
1, // formatTag (PCM)
1, // noOfChannels (mono)
8000, // samplesPerSec (8KHz)
16000, // bytesPerSec ((Sample Rate * BitsPerSample * Channels) / 8)
2, // blockAlign ((bits per sample * channels) / 8)
16, // bitsPerSample (multiples of 8)
{'d','a','t','a'}, // dataChunkID
sz // dataChunkSize (sample size)
};
return result;
}
struct voice_sync {
char* session_uuid;
Aws::IOStream *audio_stream;
switch_size_t blockAlign;
};
typedef struct voice_sync voice_sync_t;
static switch_status_t polly_file_open(switch_file_handle_t *handle, const char *path)
{
voice_sync_t *sync_info = (voice_sync_t*)malloc(sizeof(voice_sync_t));
sync_info->audio_stream = new Aws::StringStream(std::ios::in | std::ios::out | std::ios::binary);
handle->private_info = sync_info;
handle->samplerate = 8000;
handle->channels = 1;
handle->pos = 0;
handle->format = 0;
handle->sections = 0;
handle->seekable = 0;
handle->speed = 0.5;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "submitting text [%s] to polly", path);
Aws::Polly::PollyClient polly_client(*globals.credentials, *globals.config);
Aws::Polly::Model::SynthesizeSpeechRequest request;
request.SetLanguageCode(Aws::Polly::Model::LanguageCode::en_US);
request.SetOutputFormat(Aws::Polly::Model::OutputFormat::pcm);
request.SetSampleRate("8000");
request.SetTextType(Aws::Polly::Model::TextType::text); // or ssml
request.SetVoiceId(Aws::Polly::Model::VoiceId::Matthew);
request.SetText(path);
if (handle->params) {
// get the session UUID for this channel
// note: this doesnt fire for a standard call session in the audio context; is there a way to make sure it is there?
const char *uuid = switch_event_get_header(handle->params, "session");
if (!zstr(uuid)) {
sync_info->session_uuid = switch_core_strdup(handle->memory_pool, uuid);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(sync_info->session_uuid), SWITCH_LOG_DEBUG, "Polly linked to session %s\n", sync_info->session_uuid);
}
}
sync_info->audio_stream->clear();
// sync_info->audio_stream.open(filename.c_str(), std::ios::out | std::ios::binary);
auto outcome = polly_client.SynthesizeSpeech(request);
// Output operation status
if (outcome.IsSuccess()) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "received audio response for %s", request.GetServiceRequestName());
Aws::Polly::Model::SynthesizeSpeechResult& result = ((Aws::Polly::Model::SynthesizeSpeechResult&)(outcome));
Aws::IOStream* audio_stream = &result.GetAudioStream();
// this is raw PCM so we need to add a wav header!
riff header = init_pcm_header(*audio_stream);
*sync_info->audio_stream << header;
// tansfer audio data into stream
*sync_info->audio_stream << audio_stream->rdbuf();
sync_info->audio_stream->seekp(0, sync_info->audio_stream->beg);
// update handle information about audio stream
handle->samplerate = header.samplesPerSec;
handle->channels = header.noOfChannels;
handle->format = header.formatTag;
handle->duration = header.dataChunkSize / header.bytesPerSec +1;
handle->samples_in = header.dataChunkSize / header.blockAlign +1;
sync_info->blockAlign = header.blockAlign;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "polly audio stream ready; duration: %ld secs", handle->duration);
return SWITCH_STATUS_SUCCESS;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "something went wrong retrieving audio from polly");
return SWITCH_STATUS_FALSE;
}
static switch_status_t polly_file_close(switch_file_handle_t *handle)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "closiing polly audio stream");
voice_sync_t *sync_info = (voice_sync_t*)handle->private_info;
//sync_info->audio_stream->close(); -- doesnt exist on stringstream
delete sync_info->audio_stream;
if (sync_info->session_uuid) {
switch_safe_free(sync_info->session_uuid);
}
switch_safe_free(sync_info);
handle->private_info = NULL;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t polly_file_read(switch_file_handle_t *handle, void *data, size_t *len)
{
voice_sync_t *sync_info = (voice_sync_t*)handle->private_info;
switch_size_t bytes;
sync_info->audio_stream->read((char *)data, *len * sync_info->blockAlign);
if ((bytes = sync_info->audio_stream->gcount()) <= 0) {
return SWITCH_STATUS_FALSE;
}
*len = bytes / sync_info->blockAlign;
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_polly_load)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing polly audio interface");
supported_formats[0] = (char*)"polly";
/*
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
*/
switch_file_interface_t *file_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
file_interface = (switch_file_interface_t*)switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
file_interface->extens = supported_formats;
file_interface->file_open = polly_file_open;
file_interface->file_close = polly_file_close;
file_interface->file_read = polly_file_read;
MODULE_INTERFACE = *module_interface;
memset(&process, 0, sizeof(process));
memset(&globals, 0, sizeof(globals));
process.pool = pool;
switch_thread_rwlock_create(&process.running_rwlock, pool);
switch_mutex_init(&process.mutex, SWITCH_MUTEX_NESTED, pool);
globals.options = new Aws::SDKOptions();
globals.options->loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Debug;
globals.credentials = new Aws::Auth::AWSCredentials();
globals.credentials->SetAWSAccessKeyId("your aws key");
globals.credentials->SetAWSSecretKey("your aws secret");
globals.config = new Aws::Client::ClientConfiguration();
globals.config->region = "eu-west-1"; // Ireland
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing aws api");
Aws::InitAPI(*globals.options);
switch_thread_rwlock_wrlock(process.running_rwlock);
process.running = 1;
switch_thread_rwlock_unlock(process.running_rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ready to rock!");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_polly_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Shutting down polly polly audio interface");
switch_thread_rwlock_wrlock(process.running_rwlock);
process.running = 0;
switch_thread_rwlock_unlock(process.running_rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Closing aws api");
Aws::ShutdownAPI(*globals.options);
delete globals.credentials;
delete globals.config;
delete globals.options;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Module shutdown finished");
return SWITCH_STATUS_UNLOAD;
}
Now when i try to load this on Freeswitch , it throws an error
2019-07-31 22:00:51.918181 [CRIT] switch_loadable_module.c:1522 Error Loading module /usr/local/freeswitch/mod/mod_polly.so
/usr/local/freeswitch/mod/mod_polly.so: undefined symbol: _ZNK3Aws35AmazonSerializableWebServiceRequest7GetBodyEv
Freeswitch is C code with C++ guards in header files (extern "C" declaration).
Looking at symbols in mod_polly.so
readelf -Ws mod_polly.so | grep _ZNK3Aws35AmazonSerializableWebServiceRequest7GetBodyEv
66: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZNK3Aws35AmazonSerializableWebServiceRequest7GetBodyEv
590: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZNK3Aws35AmazonSerializableWebServiceRequest7GetBodyEv
Now my basic understanding of the post here tells me that the symbol is present in the so file but Freeswitch cannot find it or load it.
Now this error has very likely to do with mixing C/C++ code but looking at this and this hasn't helped me figure out how to fix it.
I do not want to build Freeswitch to load my module and I am thinking I shouldn't have to, as that renders this project un-scalable.
What am I missing here?
PS:
readelf -Ws libaws-cpp-sdk-core.a | grep AmazonSerializableWebServiceRequest7GetBodyEv
165: 0000000000000000 716 FUNC GLOBAL DEFAULT 42 _ZNK3Aws35AmazonSerializableWebServiceRequest7GetBodyEv
Symbol is defined in libaws-cpp-sdk-core.a which is part of the compilation command for mod_polly.cpp
#Sam V - turns out it was ordering issue while building. Change in ordering of build command to
g++ -shared -o mod_polly.so -fPIC -g -ggdb -std=c++11 -Wall -Werror -I/usr/src/freeswitch/src/include/ -I/usr/src/freeswitch/libs/libteletone/src/ mod_polly.cpp -L/usr/local/lib/ -laws-cpp-sdk-polly -laws-cpp-sdk-core
fixed the problem. Your 1st comment was the key. Thanks.

Undefined Reference to JNI_CreateJavaVM Eclipse and Linux

I am using Ubuntu 10.04 with Omnet++ 4.0p1 and JSimpleModule (which uses SWIG to make Java wrappers for the C++ methods found in Omnet++). I am trying to create a simulation in Java using the 2 above libraries, and when I am trying to build the project I am getting 'Undefined Reference to JNI_CreateJavaVM' as an error in JUtil.cc (which is code supplied by JSimpleModule). I have been looking around and I am including all of the proper libraries and it still isn't fixing anything. In the Omnet++ IDE (Eclipse) I am including:
/usr/lib/jvm/java-6-openjdk/include
/usr/lib/jvm/java-6-openjdk/include/linux
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client
and am linking:
/usr/lib/jvm/java-6-openjdk/jre/lib
/usr/lib/jvm/java-6-openjdk/jre/lib/client
-ljvm
I also tried compiling from the terminal using opp_makemake (which creates a Makefile) with the following parameters:
-I/usr/lib/jvm/java-6-openjdk/include
-I/usr/lib/jvm/java-6-openjdk/include/linux
-I/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client
-L/usr/lib/jvm/java-6-openjdk/jre/lib
-L/usr/lib/jvm/java-6-openjdk/jre/lib/client -ljvm
Here is the beginning of JUtil.cc up to the error (note: jni.h is included in JUtil.h):
#include "JUtil.h"
#include "JSimpleModule.h"
//#define DEBUGPRINTF printf
#define DEBUGPRINTF (void)
#ifdef _WIN32
#define PATH_SEP ";"
#else
#define PATH_SEP ":"
#endif
// This will come from the generated SimkernelJNI_registerNatives.cc
void SimkernelJNI_registerNatives(JNIEnv *jenv);
JavaVM *JUtil::vm;
JNIEnv *JUtil::jenv;
void JUtil::initJVM()
{
DEBUGPRINTF("Starting JVM...\n");
JavaVMInitArgs vm_args;
JavaVMOption options[10];
int n = 0;
const char *classpath = getenv("CLASSPATH");
if (!classpath)
opp_error("CLASSPATH environment variable is not set");
// FIXME remove hack once IDE builds the classpath corretcly
const char *classpath2 = getenv("CLASSPATH2");
std::string classpathOption = std::string("-Djava.class.path=")+(classpath2 ? classpath2 : "")+PATH_SEP+(classpath ? classpath : "");
options[n++].optionString = (char *)classpathOption.c_str(); /* user classes */
options[n++].optionString = (char *)"-Djava.library.path=."; /* set native library path */
//options[n++].optionString = "-Djava.compiler=NONE"; /* disable JIT */
//options[n++].optionString = "-verbose:jni"; /* print JNI-related messages */
//options[n++].optionString = "-verbose:class"; /* print class loading messages */
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = n;
vm_args.ignoreUnrecognized = true;
int res = JNI_CreateJavaVM(&vm, (void **)&jenv, &vm_args);
if (res<0)
opp_error("Could not create Java VM: JNI_CreateJavaVM returned %d", res);
DEBUGPRINTF("Registering native methods...\n");
SimkernelJNI_registerNatives(jenv);
DEBUGPRINTF("Done.\n");
}
If someone knows anything on how to fix this, that would be greatly appreciated. Thanks.

Libconfig edit config value

I am using libconfig to read/wirte config files in my C++ game.
Right now I just have this one config file called video.cfg:
#Video config file
video:
{
fps:
{
limited = true;
value = 20;
};
};
This config file handles the video settings of the game.
I am trying to write a very basic console program that modifies this values based on user input. However I have no idea how to do this. I can't find anything in libconfig manual and nothing on Google.
So how do you edit values in Libconfig?
#include <libconfig.h>
int main() {
config_t cfg;
config_setting_t *vid_fps_lim = 0;
config_setting_t *vid_fps_val = 0;
config_init(&cfg);
if (config_read_file(&cfg, "myconfig") == CONFIG_TRUE) {
/* lookup the settings we want */
vid_fps_lim = config_lookup(&cfg, "video.fps.limited");
vid_fps_val = config_lookup(&cfg, "video.fps.value");
/* print the current settings */
printf("video.fps.limited = %i\n", config_setting_get_bool(vid_fps_lim));
printf("video.fps.value = %i\n", config_setting_get_int(vid_fps_val));
/* modify the settings */
config_setting_set_bool(vid_fps_lim, 1);
config_setting_set_int(vid_fps_val, 60);
/* write the modified config back */
config_write_file(&cfg, "myconfig");
}
config_destroy(&cfg);
return 0;
}
I named the file "lcex.c" and the config file "myconfig" It builds and runs on my Debian Linux machine using the following...
gcc `pkg-config --cflags libconfig` lcex.c -o lcex `pkg-config --libs libconfig`
./lcex
Open your config file after running the app and you should see that the values have been updated.
Disclaimer...error handling left out to make it easier to read. I didn't build with -Wall, etc. As with any API, read the docs and handle potential errors.
I came across this question while searching for a way to have libconfig write output to a string instead of a file. I see that there's no acceptable answer here, so I thought I would provide one for posterity, even though the question is over 3 years old.
#include <stdint.h>
#include <string>
#include "libconfig.h++"
int32_t
main (void) {
libconfig::Config config;
std::string file = "test.conf";
try {
config.readFile(file.c_str());
libconfig::Setting &limited = config.lookup("video.fps.limited");
libconfig::Setting &value = config.lookup("video.fps.value");
limited = false;
value = 60;
config.writeFile(file.c_str());
}
catch (...) {
// Do something reasonable with exceptions here. Do not catch (...)
}
return 0;
}
Hope that helps someone!