| 1 | |
|---|
| 2 | #include <string> |
|---|
| 3 | #include <iostream> |
|---|
| 4 | #include <time.h> |
|---|
| 5 | #include <stdlib.h> |
|---|
| 6 | #include <string.h> |
|---|
| 7 | #include <cstdio> |
|---|
| 8 | |
|---|
| 9 | #ifdef _MSC_VER |
|---|
| 10 | #include <windows.h> |
|---|
| 11 | #define sleep(x) Sleep((x)*1000) |
|---|
| 12 | #define snprintf _snprintf |
|---|
| 13 | #endif |
|---|
| 14 | |
|---|
| 15 | using namespace std; |
|---|
| 16 | |
|---|
| 17 | #include "phapipp.h" |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | int vl1, vl2, cid1, cid2; |
|---|
| 21 | string gChatRoom; |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | string extract_uri(const char *s) |
|---|
| 25 | { |
|---|
| 26 | string tmp = s; |
|---|
| 27 | int lt = tmp.find('<'); |
|---|
| 28 | int gt = tmp.find('>'); |
|---|
| 29 | |
|---|
| 30 | return tmp.substr(lt+1, gt-lt-1); |
|---|
| 31 | |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | class myphapi:public verona::stdphapi |
|---|
| 35 | { |
|---|
| 36 | |
|---|
| 37 | static const char *nz(const char *s) { return s ? s : ""; } |
|---|
| 38 | |
|---|
| 39 | void onRegProgress(int rid, int status) |
|---|
| 40 | { |
|---|
| 41 | printf("Reg: %d Status: %d\n", rid, status); |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | virtual void onMsgProgress(int mid, const phMsgStateInfo_t *info) |
|---|
| 46 | { |
|---|
| 47 | if (info->event == phMsgNew) |
|---|
| 48 | { |
|---|
| 49 | printf("Got Message: to=%s from=%s type=%s\n======\n%s=======\n", |
|---|
| 50 | info->to, info->from, info->rawctt, info->content); |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | virtual void onNotifyProgress (const char* event, const char* from, const char *ctt, const char* content) |
|---|
| 55 | { |
|---|
| 56 | printf("Got notification: from=%s evt=%s ctt=%s content:\n====\n%s\n====\n", from, event, ctt, content); |
|---|
| 57 | } |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | void onCallProgress(int cid, const phCallStateInfo_t *info) |
|---|
| 61 | { |
|---|
| 62 | switch (info->event) |
|---|
| 63 | { |
|---|
| 64 | case phDIALING: |
|---|
| 65 | printf("DIALING line=%d cid=%d uri=%s\n", info->vlid, cid, info->u.remoteUri); |
|---|
| 66 | break; |
|---|
| 67 | |
|---|
| 68 | case phRINGING: |
|---|
| 69 | printf("RINGING cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 70 | break; |
|---|
| 71 | |
|---|
| 72 | case phRINGandSTART: |
|---|
| 73 | printf("RINGINGandSTART cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 74 | break; |
|---|
| 75 | |
|---|
| 76 | case phRINGandSTOP: |
|---|
| 77 | printf("RINGandSTOP cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 78 | break; |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | case phNOANSWER: |
|---|
| 82 | printf("NOANSWER cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 83 | break; |
|---|
| 84 | |
|---|
| 85 | case phCALLBUSY: |
|---|
| 86 | printf("BUSY cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 87 | break; |
|---|
| 88 | |
|---|
| 89 | case phCALLREDIRECTED: |
|---|
| 90 | printf("REDIRECTED cid=%d newcid=%d to=%s\n", cid, info->newcid, info->u.remoteUri); |
|---|
| 91 | break; |
|---|
| 92 | |
|---|
| 93 | case phCALLOK: |
|---|
| 94 | printf("CALLOK cid=%d uri=%s\n", cid, info->u.remoteUri); |
|---|
| 95 | break; |
|---|
| 96 | |
|---|
| 97 | case phCALLHELD: |
|---|
| 98 | printf("CALLHELD cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 99 | break; |
|---|
| 100 | |
|---|
| 101 | case phCALLRESUMED: |
|---|
| 102 | printf("CALLRESUMED cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 103 | break; |
|---|
| 104 | |
|---|
| 105 | case phHOLDOK: |
|---|
| 106 | printf("HOLDOK cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 107 | break; |
|---|
| 108 | |
|---|
| 109 | case phRESUMEOK: |
|---|
| 110 | printf("RESUMEOK cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 111 | break; |
|---|
| 112 | |
|---|
| 113 | case phINCALL: |
|---|
| 114 | printf("INCALL line=%d cid=%d to=%s from=%s streams=%x callinfo=%s\n", info->vlid, cid, |
|---|
| 115 | info->localUri, info->u.remoteUri, info->streams, nz(info->callinfo)); |
|---|
| 116 | |
|---|
| 117 | if (info->streams == PH_STREAM_DATA) |
|---|
| 118 | { |
|---|
| 119 | acceptCall(cid, 0, PH_STREAM_DATA); |
|---|
| 120 | cid2 = cid; |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | break; |
|---|
| 124 | |
|---|
| 125 | case phCALLCLOSED: |
|---|
| 126 | printf("CALLCLOSED cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 127 | break; |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | case phCALLCLOSEDandSTOPRING: |
|---|
| 131 | printf("CALLCLOSEDandSTOPRING cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 132 | break; |
|---|
| 133 | |
|---|
| 134 | case phCALLERROR: |
|---|
| 135 | printf("CALLERROR cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 136 | break; |
|---|
| 137 | |
|---|
| 138 | case phDTMF: |
|---|
| 139 | printf("DTMF cid=%d digit=%c\n", cid, info->u.dtmfDigit); |
|---|
| 140 | break; |
|---|
| 141 | |
|---|
| 142 | case phXFERREQ: |
|---|
| 143 | printf("XFERREQ line=%d cid=%d newcid=%d to=%s", info->vlid, cid, info->newcid, info->u.remoteUri); |
|---|
| 144 | break; |
|---|
| 145 | |
|---|
| 146 | case phXFERPROGRESS: |
|---|
| 147 | printf("XFERPROGRESS cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 148 | break; |
|---|
| 149 | |
|---|
| 150 | case phXFEROK: |
|---|
| 151 | printf("XFEROK cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 152 | break; |
|---|
| 153 | |
|---|
| 154 | case phXFERFAIL: |
|---|
| 155 | printf("XFERFAIL cid=%d status=%d\n", cid, info->u.errorCode); |
|---|
| 156 | break; |
|---|
| 157 | |
|---|
| 158 | case phCALLREPLACED: |
|---|
| 159 | printf("CALLREPLACED cid=%d newcid=%d uri=%s streams=%x, callinfo=%s\n", cid, info->newcid, |
|---|
| 160 | info->u.remoteUri, info->streams, nz(info->callinfo)); |
|---|
| 161 | |
|---|
| 162 | gChatRoom = extract_uri(info->u.remoteUri); |
|---|
| 163 | cid1 = info->newcid; |
|---|
| 164 | |
|---|
| 165 | phCloseCall(cid); |
|---|
| 166 | break; |
|---|
| 167 | |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | fflush(stdout); |
|---|
| 171 | |
|---|
| 172 | |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | }; |
|---|
| 178 | |
|---|
| 179 | |
|---|
| 180 | extern myphapi api; |
|---|
| 181 | |
|---|
| 182 | |
|---|
| 183 | static char * |
|---|
| 184 | maketimestamp(char buf[], int bsize) |
|---|
| 185 | { |
|---|
| 186 | struct tm tmbuf; |
|---|
| 187 | time_t now; |
|---|
| 188 | char tmstr[64]; |
|---|
| 189 | |
|---|
| 190 | now = time(0); |
|---|
| 191 | tmbuf = *localtime(&now); |
|---|
| 192 | |
|---|
| 193 | strftime(tmstr, 64, "%d-%b-%Y %I:%M:%S", &tmbuf); |
|---|
| 194 | |
|---|
| 195 | snprintf(buf, bsize, "%s.%03d %s", |
|---|
| 196 | tmstr, now % 1000, |
|---|
| 197 | ((tmbuf.tm_hour < 12) ? "AM" : "PM")); |
|---|
| 198 | |
|---|
| 199 | return buf; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | |
|---|
| 203 | std::string gChatUri = "sip:CHAT@comverse.com"; |
|---|
| 204 | |
|---|
| 205 | void sendSessionMessage(int vlid, const std::string &chatroom, const char *from, const char *message) |
|---|
| 206 | { |
|---|
| 207 | char mid[64]; |
|---|
| 208 | char cpimbuf[4096]; |
|---|
| 209 | char timestamp[128]; |
|---|
| 210 | |
|---|
| 211 | |
|---|
| 212 | maketimestamp(timestamp, sizeof(timestamp)); |
|---|
| 213 | |
|---|
| 214 | sprintf(mid, "%d", time(0)); |
|---|
| 215 | |
|---|
| 216 | snprintf(cpimbuf, sizeof(cpimbuf), |
|---|
| 217 | "To: %s\r\n" |
|---|
| 218 | "From: %s\r\n" |
|---|
| 219 | "DateTime: %s\r\n" |
|---|
| 220 | "Subject: \r\n" |
|---|
| 221 | "Expires: %d\r\n" |
|---|
| 222 | "imdn.Message-ID: %s\r\n" |
|---|
| 223 | "imdn.Disposition-Notification: \r\n" |
|---|
| 224 | "Content-Type: text/html\r\n" |
|---|
| 225 | "\r\n", |
|---|
| 226 | chatroom.c_str(), from, timestamp, 3600, mid); |
|---|
| 227 | |
|---|
| 228 | ::strcat(cpimbuf, message); |
|---|
| 229 | |
|---|
| 230 | api.sendMessage(vlid, gChatUri, cpimbuf, "message/cpim", gChatUri); |
|---|
| 231 | |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | |
|---|
| 236 | const char * |
|---|
| 237 | getMobilityString(int vlid) |
|---|
| 238 | { |
|---|
| 239 | switch(api.mobility(vlid)) |
|---|
| 240 | { |
|---|
| 241 | case PH_LINE_MOBILITY_FIXED: |
|---|
| 242 | return "fixed"; |
|---|
| 243 | |
|---|
| 244 | case PH_LINE_MOBILITY_MOBILE: |
|---|
| 245 | return "mobile"; |
|---|
| 246 | |
|---|
| 247 | default: |
|---|
| 248 | case PH_LINE_MOBILITY_DEFAULT: |
|---|
| 249 | return ""; |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | } |
|---|
| 253 | |
|---|
| 254 | void remove_port(std::string& s) |
|---|
| 255 | { |
|---|
| 256 | int colon = s.rfind(':'); |
|---|
| 257 | int at = s.find('@'); |
|---|
| 258 | |
|---|
| 259 | if (colon > at && colon != s.npos) |
|---|
| 260 | s.replace(colon, s.length() - colon, ""); |
|---|
| 261 | |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | std::string |
|---|
| 265 | getEntity(int vlid) |
|---|
| 266 | { |
|---|
| 267 | std::string tmp = api.getSipAddress(vlid); |
|---|
| 268 | std::string sa = extract_uri(tmp.c_str()); |
|---|
| 269 | |
|---|
| 270 | remove_port(sa); |
|---|
| 271 | sa.replace(0,4, ""); // remove "sip:" |
|---|
| 272 | return sa; |
|---|
| 273 | |
|---|
| 274 | } |
|---|
| 275 | #define PUBLISH_MSG_TEMPLATE_WITH_DEVTYPE "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ |
|---|
| 276 | <presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n entity=\"%s\">\n\ |
|---|
| 277 | <tuple id=\"%s%s\">\n\ |
|---|
| 278 | <status><basic>%s</basic></status>\n\ |
|---|
| 279 | <activities>%s</activities>\n\ |
|---|
| 280 | <note>%s</note>\n\ |
|---|
| 281 | <contact priority=\"1\">%s</contact>\n\ |
|---|
| 282 | <time>%u</time>\n\ |
|---|
| 283 | </tuple>\n\ |
|---|
| 284 | </presence>\n" |
|---|
| 285 | |
|---|
| 286 | void publishPresence(int vlid, bool status,const std::string& activity, int timeout) |
|---|
| 287 | { |
|---|
| 288 | |
|---|
| 289 | char *body = new char[4*1024]; |
|---|
| 290 | std::string prefix = getMobilityString(vlid); |
|---|
| 291 | std::string uri = getEntity(vlid); |
|---|
| 292 | std::string realAct = activity; |
|---|
| 293 | const char *mood="1"; |
|---|
| 294 | |
|---|
| 295 | |
|---|
| 296 | if (prefix.length()) |
|---|
| 297 | prefix += "."; |
|---|
| 298 | |
|---|
| 299 | snprintf(body, 4*1024, PUBLISH_MSG_TEMPLATE_WITH_DEVTYPE, |
|---|
| 300 | uri.c_str(), |
|---|
| 301 | prefix.c_str(), |
|---|
| 302 | uri.c_str(), |
|---|
| 303 | (status ? "open" : "closed"), |
|---|
| 304 | realAct.c_str(), |
|---|
| 305 | mood, |
|---|
| 306 | uri.c_str(), |
|---|
| 307 | time(0)); |
|---|
| 308 | |
|---|
| 309 | |
|---|
| 310 | api.publish(vlid, "sip:" + uri, "presence" , "application/pidf+xml", body, timeout); |
|---|
| 311 | |
|---|
| 312 | delete [] body; |
|---|
| 313 | |
|---|
| 314 | |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | |
|---|
| 319 | |
|---|
| 320 | void joinServerChat(const std::string& chatroom, int vlid, int cid) |
|---|
| 321 | { |
|---|
| 322 | std::string cidstr = api.getSipCallID(cid); |
|---|
| 323 | |
|---|
| 324 | api.sendMessage(vlid, chatroom, "Join", "text/plain", gChatUri, cidstr); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | |
|---|
| 328 | |
|---|
| 329 | |
|---|
| 330 | |
|---|
| 331 | |
|---|
| 332 | |
|---|
| 333 | |
|---|
| 334 | myphapi api; |
|---|
| 335 | |
|---|
| 336 | |
|---|
| 337 | |
|---|
| 338 | int main(int argc, char *argv[]) |
|---|
| 339 | { |
|---|
| 340 | |
|---|
| 341 | cout << "Intializing and creating virtual lines " << endl; |
|---|
| 342 | api.init(); |
|---|
| 343 | |
|---|
| 344 | api.addCustomHeader("INVITE", "Expires", "3600"); |
|---|
| 345 | |
|---|
| 346 | api.addAuthInfo(argv[1], argv[1], argv[2], "voip.mbdsys.com"); |
|---|
| 347 | |
|---|
| 348 | vl1 = api.addVline(argv[1], argv[1], "voip.mbdsys.com", "voip.mbdsys.com:6060", 600); |
|---|
| 349 | |
|---|
| 350 | string s; |
|---|
| 351 | |
|---|
| 352 | |
|---|
| 353 | cout << "Placeing data call " << endl; |
|---|
| 354 | cin >> s; |
|---|
| 355 | |
|---|
| 356 | // place data call |
|---|
| 357 | |
|---|
| 358 | ph_config_t* conf = api.getConfig(); |
|---|
| 359 | strcpy(conf->audio_codecs, "PCMA,PCMU"); |
|---|
| 360 | strcpy(conf->local_rtp_port, "27000"); |
|---|
| 361 | |
|---|
| 362 | cid1 = api.placeCall(vl1, "sip:10001@sfrdroid", 0, 0, PH_STREAM_AUDIO, 0, "voip.mbdsys.com"); |
|---|
| 363 | sleep(5); |
|---|
| 364 | /* |
|---|
| 365 | cout << "netc1 joining chatroom: " << endl; |
|---|
| 366 | cin >> s; |
|---|
| 367 | |
|---|
| 368 | joinServerChat(gChatRoom, vl1, cid1); |
|---|
| 369 | sleep(3); |
|---|
| 370 | |
|---|
| 371 | cout << "netc2 joining chatroom: " << endl; |
|---|
| 372 | cin >> s; |
|---|
| 373 | |
|---|
| 374 | joinServerChat(gChatRoom, vl2, cid2); |
|---|
| 375 | sleep(3); |
|---|
| 376 | |
|---|
| 377 | cout << "netc1 sending message: " << endl; |
|---|
| 378 | cin >> s; |
|---|
| 379 | |
|---|
| 380 | sendSessionMessage(vl1, gChatRoom, "sip:netc1@comverse.com", "hello you"); |
|---|
| 381 | sleep(3); |
|---|
| 382 | */ |
|---|
| 383 | cout << "Closing data calls" << endl; |
|---|
| 384 | cin >> s; |
|---|
| 385 | |
|---|
| 386 | api.closeCall(cid1); |
|---|
| 387 | // api.closeCall(cid2); |
|---|
| 388 | return 0; |
|---|
| 389 | sleep(3); |
|---|
| 390 | |
|---|
| 391 | cout << "subscribing to netc2 presence" << endl; |
|---|
| 392 | cin >> s; |
|---|
| 393 | |
|---|
| 394 | api.subscribe(vl1, "sip:netc2@comverse.com", PH_SUBS_PRESENCE); |
|---|
| 395 | sleep(3); |
|---|
| 396 | |
|---|
| 397 | cout << "Publishing netc2 presence" << endl; |
|---|
| 398 | cin >> s; |
|---|
| 399 | |
|---|
| 400 | publishPresence(vl2, true, "online", 300); |
|---|
| 401 | sleep(3); |
|---|
| 402 | |
|---|
| 403 | cout << "Publishing changed netc2 presence" << endl; |
|---|
| 404 | cin >> s; |
|---|
| 405 | |
|---|
| 406 | publishPresence(vl2, true, "busy", 300); |
|---|
| 407 | sleep(3); |
|---|
| 408 | |
|---|
| 409 | |
|---|
| 410 | cout << "Terminating" << endl; |
|---|
| 411 | cin >> s; |
|---|
| 412 | |
|---|
| 413 | api.terminate(); |
|---|
| 414 | } |
|---|