I'm trying to send sms messages through pjsip without luck so far.
The account gets registered on a server and I get a register success response but I can't find any good tutorials that show how to send sms.
I found this book online but it still doesn't give me any examples of how to use this library:
http://www.scribd.com/doc/90092246/Pjsip-Dev-Guide#outer_page_48
I know I'm supposed to use:
pjsip_endpt_create_request(pjsip_endpoint *endpt, const pjsip_method method, const pj_str_t *target, const pj_str_t *from, const pj_str_t *to, , const pj_str_t *call_id, int cseq, const pj_str_t *text, pjsip_tx_data **p_tdata);
pjsip_endpt_acquire_transport(pjsip_endpoint *endpt, pjsip_transport_type_e type, const pj_sockaddr_t *remote, int addr_len, const pjsip_tpselector *sel, pjsip_transport **p_tp)
but apart from these, I have no idea.
Note: I don't want instant messaging, I want the texts to be delivered as SMS if possible.
And it needs to be done in pjsip, no other library (no flexibility unfortunately).
Thanks in advance!
Okay, here I am answering my own question related to pjsip again. I wish this library had proper documentation where the function calls were explained a better way on what they do.
1 thing that confused me was that there in this developer's guide: http://www.pjsip.org/release/0.5.4/PJSIP-Dev-Guide.pdf
there are 2 topics. 1 is message elements and how to create a request. The other is instant messaging. I wasn't exactly sure which was required for SMS. Turns out, its the instant messaging.
The only needed function is:
pjsua_im_send(pjsua_acc_id acc_id, const pj_str_t *to, const pj_str_t *mime_type, const pj_str_t *content, const pjsua_msg_data *msg_data, void *user_data);
1st variable acc_id is what gets initialized at the beginning of the application SIP registration.
2nd variable is the number you want the message to be sent to. I initialized it as such:
"sip:16476804556#sipserverdomain.com"
3rd variable is for sending MIME's. I didn't use this. so it's NULL.
4th variable is the message body itself.
For example:
pj_str_t text;
const char *msgText = [#"Hello there!" UTF8String];
text = pj_str((char*)msgText);
then I passed: &text to the function.
5th variable is the msg data. Again, didn't use it. It's NULL.
6th variable is user data. Didn't use this either. NULL.
And finally, this is what the function call looked like:
pjsua_im_send(app._sip_acc_id, &to, NULL, &text, NULL, NULL);
Hope this helps someone out there having a similar problem!
-c0d3Junk13
A SMS is essentially an email delivered to phonenumber#serviceprovider.com. I have not used pjsip, however I was able to use the Chilkat library to deliver SMS quite easily. For example code to send an email, you can find it on their website.
Related
I am using compiled version of rtmp-dump from github in my iOS project. Following is the code to connect to the server.
rtmp = RTMP_Alloc();
RTMP_Init(rtmp);
NSString *url = #"rtmp://192.168.0.119:1935/red5/sw231/";
char *strUrl = (char *)[url cStringUsingEncoding:NSASCIIStringEncoding];
RTMP_SetupURL(rtmp, strUrl);
RTMP_Connect(rtmp, NULL);
Since the proper documentation of rtmp-dump OR lib-rtmp is not available I want to know the methods that I can use for the following functionalities.
I want to send an array of values while connecting. My query is by what method of rtmp-dump can I send values to the server when connecting?
How can I call certain methods of the server and pass parameters to the server?
How can I receive response from the server? As well as how can I implement client-side method invocation through rtmp-dump?
How can I explicitly provide the name of the stream which I want to play or listen to after connecting?
By using RTMP_Close(), will I be able to disconnect the connection?
I know this post was asked 12 months ago but this may be usefull.
Download this and see the examples of usage of librtmp. I don't know why this library has no documentation but following that examples can help you a bit.
I'm studying c socket programming lately,so I write an example for practice of Client–server model. I use structure as message data to send to server, server processes the data. when i run in the IOS simulator, it's right, but in the device it's wrong, I find that the structure data which the server receives from the devices client is different from the client message data! I'm sorry my English is very bad.
my structure code is:
typedef struct Message
{
char msg[4000];
char name[256];
bool isBroadcast;
bool islogin;
USER userInfo;
}__attribute__((packed)) MessageType;
user code is :
typedef struct user
{
int id_number;
char name[256];
char password[20];
char *p_chatlog;
struct sockaddr user_addr;
int sock;
} __attribute__((packed)) USER;
send code is :
MessageType *loginMsg = (MessageType *)malloc(sizeof(MessageType));
bzero(loginMsg, sizeof(MessageType));
loginMsg->islogin = true;
const char *name_str = [userName.text UTF8String];
memcpy(&(loginMsg->userInfo.name), name_str, strlen(name_str));
const char *password_str = [password.text UTF8String];
memcpy(&(loginMsg->userInfo.password), password_str, strlen(password_str));
write(m_sock, loginMsg, sizeof(MessageType));
free(loginMsg);
server receive code use read() function, then make the receive chars transform structure type.
I would suggest that you make sure you send the data in network byte order; use the htonl, htons and ntohl, ntohs system functions. Different devices may well be a different endianness. Also, you probably shouldn't just send a struct over the network, even in network byte order, you would be better devising a simple protocol to send the data you require - it's more maintainable and flexible. You also can't guarantee your write has sent all of the data you requested, you should check the return results of both your read and write to ensure you have the amount you expect.
Incidentally, it is recommended to avoid the POSIX networking library for iOS and use the native implementation where possible.
What's the best way to look up the meaning of OSStatus errors ( i.e. -43 ) in Core Audio? Is there a way to process them in your iOS code so they can be formatted to show up with a brief explanation in the console?
After a quick look around, the best way so far seems to be to use the Unix command line tool - macerror - and type in the error code as an argument: not sure if it's possible to call & get the results of a macerror query from my Obj-C code in iOS into a console print out.
A recent article in IOS Dev Weekly linked to a great webpage that allows you to search for all OSStatus codes. Definitely worth bookmarking.
A bit late to the party, but I just noticed that at least one error code (560226676) is actual a four-letter code; it can be represented as '!dat' in big-endian. Searching for that gives kAudioDeviceUnsupportedFormatError.
IOW, it can't hurt to print error codes with a little function like this:
char *OSTStr( OSType type )
{
static union OSTStr {
uint32_t four;
char str[5];
} ltype;
ltype.four = EndianU32_BtoN(type);
ltype.str[4] = '\0';
return ltype.str;
}
I'm currently trying to write an application that intercepts text messages and reacts depending on the content of that message.
I tried to hook into _receivedMessage:(struct __CKSMSRecord *)message replace:(BOOL)replace method in the CKSMSService class but this seems not do get called at all.
Could someone please tell me what function/class i have to hook in? I need to intercept the text message before it gets displayed and stored into the database. I'm on IOS 5.0.1.
Any help is truly appreciated.
This code snippet should intercept SMS messages- You can extend it for other kinds of notifications. Will work on iOS 5.0.1 as well. Does not work with iMessages though. Link with CoreTelephony framework (there are bunch of private headers there which you'd can class-dump)
#include <dlfcn.h>
#define CORETELPATH "/System/Library/PrivateFrameworks/CoreTelephony.framework/CoreTelephony"
id(*CTTelephonyCenterGetDefault)();
void (*CTTelephonyCenterAddObserver) (id,id,CFNotificationCallback,NSString*,void*,int);
static void telephonyEventCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSString *notifyname=(NSString *)name;
if ([notifyname isEqualToString:#"kCTMessageReceivedNotification"])//received SMS
{
NSLog(#" SMS Notification Received :kCTMessageReceivedNotification");
// Do blocking here.
}
}
-(void) registerCallback {
void *handle = dlopen(CORETELPATH, RTLD_LAZY);
CTTelephonyCenterGetDefault = dlsym(handle, "CTTelephonyCenterGetDefault");
CTTelephonyCenterAddObserver = dlsym(handle,"CTTelephonyCenterAddObserver");
dlclose(handle);
id ct = CTTelephonyCenterGetDefault();
CTTelephonyCenterAddObserver(
ct,
NULL,
telephonyEventCallback,
NULL,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}
Although the poster already accepted rajagp's answer, I'm pretty sure it doesn't do what the question actually asked, on iOS 5. For iOS 5, I'm no longer seeing the message content anymore, although I do get notified that there is a new message.
So, what I did is take rajagp's notification handler for kCTMessageReceivedNotification, and inside it, use the code posted here to actually get the content of the text message, from the SMS database.
This still works on iOS 7, but I found that you need a slight delay after receiving the kCTMessageReceivedNotification notification. Else you will miss the SMS just received. I use a delay of 0.1 sec, with a [self performSelector .. afterDelay:0.1];
I'm working on a little hack sending MIDI messages from an app using RtMidi as a wrapper for CoreMIDI on OS X. I use RtMidiOut::openVirtualPort("MyAwesomePort") so I can select my app as an input source in a DAW.
However, if my program closes and I open it again, my DAW does not recognize the input device as the same port, despite being given the same name.
I was originally using pyrtmidi, so went and verified the behavior writing in C++ directly with RtMidi. "My DAW" in this case is Reaper 4, but I've duplicated the behavior in Pro Tools, Logic, and MuLab.
I know it's possible to retain some uniqueness of a virtual midi port, since MidiKeys behaves just as I'd like my application to behave: my DAWs remember it even if MidiKeys closes and re-opens while my DAW is still running.
So I dug into the RtMidi source, and the CoreMIDI wrapper seemed straightforward enough. All that the MIDISourceCreate asks for is a string. The client parameter is (what I presume after browsing the docs) an identifier for my application, it being a client of the CoreMIDI services.
void RtMidiOut :: openVirtualPort( std::string portName )
{
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
if ( data->endpoint ) {
errorString_ = "RtMidiOut::openVirtualPort: a virtual output port already exists!";
error( RtError::WARNING );
return;
}
// Create a virtual MIDI output source.
MIDIEndpointRef endpoint;
OSStatus result = MIDISourceCreate( data->client,
CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ),
&endpoint );
if ( result != noErr ) {
errorString_ = "RtMidiOut::initialize: error creating OS-X virtual MIDI source.";
error( RtError::DRIVER_ERROR );
}
// Save our api-specific connection information.
data->endpoint = endpoint;
}
So I looked at the MIDISourceCreate documentation, and read this:
After creating a virtual source, it's a good idea to assign it the same unique ID it had the last time your application created it. (Although you should be prepared for this to fail in the unlikely event of a collision.) This will permit other clients to retain persistent references to your virtual source more easily.
This seems like exactly what I'm looking for. Except I have no idea how to assign the source a unique ID. The out parameter for MIDISourceCreate is a MIDIEndpointRef, which according to the docs is just typedef'd to a UInt32 down the line. So I hypothesized that maybe I should keep track of this UInt32, but that seems like a bad idea.
After digging through all of this I feel like I'm hitting a bit of a brick wall. How do I retain the uniqueness of my MIDI port in between runs of my application?
According to the docs,
kMIDIPropertyUniqueID
The system assigns unique ID's to all objects. Creators of virtual endpoints may set this property on their endpoints, though doing so may fail if the chosen ID is not unique.
So maybe something like this:
// Try to set the ID if it's saved.
if (savedUniqueId) {
OSStatus result = MIDIObjectSetIntegerProperty(endpoint, kMIDIPropertyUniqueID, myUniqueId);
if (result == kMIDIIDNotUnique) {
savedUniqueId = 0;
}
}
// If not saved, record the system-assigned ID
if (!savedUniqueId) {
OSStatus result = MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &savedUniqueId);
// Handle the error?
}
The unique ID is typedefed to a SInt32. I've made the assumption that 0 is an invalid unique ID, which is at least true for connections (the docs for kMIDIPropertyConnectionUniqueID say it's "non-existant or 0 if there is no connection").
I'm not sure how you maintain long-term uniqueness with only 32 bits, but it'll hopefully be sufficient for relaunches of your app.