/* * pj_file_size() */ PJ_DEF(pj_off_t) pj_file_size(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; DWORD sizeLo, sizeHi; pj_off_t size; PJ_ASSERT_RETURN(filename != NULL, -1); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return -1; sizeLo = GetFileSize(hFile, &sizeHi); if (sizeLo == INVALID_FILE_SIZE) { DWORD dwStatus = GetLastError(); if (dwStatus != NO_ERROR) { CloseHandle(hFile); return -1; } } size = sizeHi; size = (size << 32) + sizeLo; CloseHandle(hFile); return size; }
static void write_log(int level, const char *data, int len) { PJ_DECL_UNICODE_TEMP_BUF(wdata,256); PJ_UNUSED_ARG(level); PJ_UNUSED_ARG(len); SendMessage(hwndLog, EM_REPLACESEL, FALSE, (LPARAM)PJ_STRING_TO_NATIVE(data,wdata,256)); }
static void OnError (const wchar_t *title, pj_status_t status) { char errmsg[PJ_ERR_MSG_SIZE]; PJ_DECL_UNICODE_TEMP_BUF (werrmsg, PJ_ERR_MSG_SIZE); pj_strerror (status, errmsg, sizeof (errmsg)); MessageBox (NULL, PJ_STRING_TO_NATIVE (errmsg, werrmsg, PJ_ERR_MSG_SIZE), title, MB_OK); }
/* * pj_file_delete() */ PJ_DEF(pj_status_t) pj_file_delete(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL); if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; }
/** * Incoming IM message (i.e. MESSAGE request)! */ static void on_pager(pjsua_call_id call_id, const pj_str_t *from, const pj_str_t *to, const pj_str_t *contact, const pj_str_t *mime_type, const pj_str_t *text) { // allocate buffer wchar_t* tfrom = (wchar_t*)pj_pool_alloc(app_config.pool, 255); wchar_t* ttext = (wchar_t*)pj_pool_alloc(app_config.pool, 255); /* Note: call index may be -1 */ PJ_UNUSED_ARG(call_id); PJ_UNUSED_ARG(to); PJ_UNUSED_ARG(contact); PJ_UNUSED_ARG(mime_type); PJ_LOG(3,(THIS_FILE,"MESSAGE from %.*s: %.*s (%.*s)", (int)from->slen, from->ptr, (int)text->slen, text->ptr, (int)mime_type->slen, mime_type->ptr)); if (cb_messagereceived != 0) (*cb_messagereceived)(PJ_STRING_TO_NATIVE(from->ptr, tfrom, sizeof(tfrom)), PJ_STRING_TO_NATIVE(text->ptr, ttext, sizeof(ttext))); }
/* * pj_file_move() */ PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname) { PJ_DECL_UNICODE_TEMP_BUF(woldname,256) PJ_DECL_UNICODE_TEMP_BUF(wnewname,256) BOOL rc; PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL); #if PJ_WIN32_WINNT >= 0x0400 rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING); #else rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname))); #endif if (!rc) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; }
PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool, const char *pathname, unsigned flags, pj_oshandle_t *fd) { PJ_DECL_UNICODE_TEMP_BUF(wpathname,256) HANDLE hFile; DWORD dwDesiredAccess = 0; DWORD dwShareMode = 0; DWORD dwCreationDisposition = 0; DWORD dwFlagsAndAttributes = 0; PJ_UNUSED_ARG(pool); PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL); if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) { dwDesiredAccess |= GENERIC_WRITE; if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { dwDesiredAccess |= FILE_APPEND_DATA; } else { dwDesiredAccess &= ~(FILE_APPEND_DATA); dwCreationDisposition |= CREATE_ALWAYS; } } if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) { dwDesiredAccess |= GENERIC_READ; if (flags == PJ_O_RDONLY) dwCreationDisposition |= OPEN_EXISTING; } if (dwDesiredAccess == 0) { pj_assert(!"Invalid file open flags"); return PJ_EINVAL; } dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; hFile = CreateFile(PJ_STRING_TO_NATIVE(pathname,wpathname,sizeof(wpathname)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { *fd = 0; return PJ_RETURN_OS_ERROR(GetLastError()); } *fd = hFile; return PJ_SUCCESS; }
/* * pj_file_exists() */ PJ_DEF(pj_bool_t) pj_file_exists(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; PJ_ASSERT_RETURN(filename != NULL, 0); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; CloseHandle(hFile); return PJ_TRUE; }
/* * Handler on buddy state changed. */ static void on_buddy_state(pjsua_buddy_id buddy_id) { pjsua_buddy_info info; pjsua_buddy_get_info(buddy_id, &info); PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s", (int)info.uri.slen, info.uri.ptr, (int)info.status_text.slen, info.status_text.ptr)); wchar_t* text = (wchar_t*)pj_pool_alloc(app_config.pool, 255); text = PJ_STRING_TO_NATIVE(info.status_text.ptr, text, info.status_text.slen); // callback if (cb_buddystatus != 0) cb_buddystatus(buddy_id, info.status, text); }
/* * pj_file_getstat() */ PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; DWORD sizeLo, sizeHi; FILETIME creationTime, accessTime, writeTime; PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL); hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return PJ_RETURN_OS_ERROR(GetLastError()); sizeLo = GetFileSize(hFile, &sizeHi); if (sizeLo == INVALID_FILE_SIZE) { DWORD dwStatus = GetLastError(); if (dwStatus != NO_ERROR) { CloseHandle(hFile); return PJ_RETURN_OS_ERROR(dwStatus); } } stat->size = sizeHi; stat->size = (stat->size << 32) + sizeLo; if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) { DWORD dwStatus = GetLastError(); CloseHandle(hFile); return PJ_RETURN_OS_ERROR(dwStatus); } CloseHandle(hFile); if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS) return PJ_RETURN_OS_ERROR(GetLastError()); file_time_to_time_val(&accessTime, &stat->atime); file_time_to_time_val(&writeTime, &stat->mtime); return PJ_SUCCESS; }
/** * Handler when there is incoming call. */ static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_rx_data *rdata) { pjsua_call_info call_info; pjsua_call_get_info(call_id, &call_info); wchar_t* tremcontat = (wchar_t*)pj_pool_alloc(app_config.pool, 255); tremcontat = PJ_STRING_TO_NATIVE(call_info.remote_contact.ptr, tremcontat, call_info.remote_contact.slen); PJ_LOG(3,(THIS_FILE, "Incoming Call %d, Remote contact: %s", call_id, tremcontat)); if (cb_callincoming != 0) { cb_callincoming(call_id, tremcontat); } }
////////////////////////////////////////////////////////////////////////// // Request handler to receive out-of-dialog NOTIFY (from Asterisk) static pj_bool_t on_rx_request(pjsip_rx_data *rdata) { if (strstr(pj_strbuf(&rdata->msg_info.msg->line.req.method.name), "NOTIFY")) { pjsip_generic_string_hdr * hdr; pj_str_t did_str = pj_str("Event"); hdr = (pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &did_str, NULL); if (!hdr) return false; // We have an event header, now determine if it's contents are "message-summary" if (pj_strcmp2(&hdr->hvalue, "message-summary")) return false; pjsip_msg_body * body_p = rdata->msg_info.msg->body; wchar_t* buf = (wchar_t*)pj_pool_alloc(app_config.pool, body_p->len); buf = PJ_STRING_TO_NATIVE((char*)body_p->data, buf, body_p->len); // Process body message as desired... if (strncmp((char*)body_p->data, "Messages-Waiting: yes", body_p->len) != 0) { if (cb_mwi != 0) cb_mwi(1, buf); } else { if (cb_mwi != 0) cb_mwi(0, buf); } PJ_LOG(3,(THIS_FILE,"MWI message: %s", buf)); } pjsip_endpt_respond_stateless(pjsip_ua_get_endpt(pjsip_ua_instance()), rdata, 200, NULL, NULL, NULL); return PJ_TRUE; }
/* * Convert text to IPv4/IPv6 address. */ PJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst) { char tempaddr[PJ_INET6_ADDRSTRLEN]; PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL); /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be * compatible with pj_inet_aton() */ if (af==PJ_AF_INET) { ((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE; } /* Caution: * this function might be called with cp->slen >= 46 * (i.e. when called with hostname to check if it's an IP addr). */ if (src->slen >= PJ_INET6_ADDRSTRLEN) { return PJ_ENAMETOOLONG; } pj_memcpy(tempaddr, src->ptr, src->slen); tempaddr[src->slen] = '\0'; #if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0 /* * Implementation using inet_pton() */ if (inet_pton(af, tempaddr, dst) != 1) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) /* * Implementation on Windows, using WSAStringToAddress(). * Should also work on Unicode systems. */ { PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) pj_sockaddr sock_addr; int addr_len = sizeof(sock_addr); int rc; sock_addr.addr.sa_family = (pj_uint16_t)af; rc = WSAStringToAddress( PJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)), af, NULL, (LPSOCKADDR)&sock_addr, &addr_len); if (rc != 0) { /* If you get rc 130022 Invalid argument (WSAEINVAL) with IPv6, * check that you have IPv6 enabled (install it in the network * adapter). */ pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } if (sock_addr.addr.sa_family == PJ_AF_INET) { pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4); return PJ_SUCCESS; } else if (sock_addr.addr.sa_family == PJ_AF_INET6) { pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16); return PJ_SUCCESS; } else { pj_assert(!"Shouldn't happen"); return PJ_EBUG; } } #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 /* IPv6 support is disabled, just return error without raising assertion */ return PJ_EIPV6NOTSUP; #else pj_assert(!"Not supported"); return PJ_EIPV6NOTSUP; #endif }
PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool, const char *pathname, unsigned flags, pj_oshandle_t *fd) { PJ_DECL_UNICODE_TEMP_BUF(wpathname,256) HANDLE hFile; DWORD dwDesiredAccess = 0; DWORD dwShareMode = 0; DWORD dwCreationDisposition = 0; DWORD dwFlagsAndAttributes = 0; PJ_UNUSED_ARG(pool); PJ_ASSERT_RETURN(pathname!=NULL, PJ_EINVAL); if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) { dwDesiredAccess |= GENERIC_WRITE; if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { #if !defined(PJ_WIN32_WINCE) || !PJ_WIN32_WINCE /* FILE_APPEND_DATA is invalid on WM2003 and WM5, but it seems * to be working on WM6. All are tested on emulator though. * Removing this also seem to work (i.e. data is appended), so * I guess this flag is "optional". * See http://trac.pjsip.org/repos/ticket/825 */ dwDesiredAccess |= FILE_APPEND_DATA; #endif dwCreationDisposition |= OPEN_ALWAYS; } else { dwDesiredAccess &= ~(FILE_APPEND_DATA); dwCreationDisposition |= CREATE_ALWAYS; } } if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) { dwDesiredAccess |= GENERIC_READ; if (flags == PJ_O_RDONLY) dwCreationDisposition |= OPEN_EXISTING; } if (dwDesiredAccess == 0) { pj_assert(!"Invalid file open flags"); return PJ_EINVAL; } dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; hFile = CreateFile(PJ_STRING_TO_NATIVE(pathname,wpathname,sizeof(wpathname)), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { *fd = 0; return PJ_RETURN_OS_ERROR(GetLastError()); } if ((flags & PJ_O_APPEND) == PJ_O_APPEND) { pj_status_t status; status = pj_file_setpos(hFile, 0, PJ_SEEK_END); if (status != PJ_SUCCESS) { pj_file_close(hFile); return status; } } *fd = hFile; return PJ_SUCCESS; }