64 #include <sys/socket.h>
66 #include <arpa/inet.h>
68 #include <sys/ioctl.h>
71 #include <semaphore.h>
136 #if defined(AST_MISDN_ENHANCEMENTS)
141 #define MISDN_CC_RECORD_AGE_MAX (6UL * 60 * 60)
143 #define MISDN_CC_REQUEST_WAIT_MAX 5
155 struct misdn_cc_caller {
160 struct misdn_cc_notify {
172 struct misdn_cc_record {
205 int requested_retention;
210 int retention_enabled;
233 int outstanding_message;
236 int activation_requested;
246 enum FacErrorCode error_code;
249 enum FacRejectCode reject_code;
263 struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
273 struct misdn_cc_notify remote_user_free;
276 struct misdn_cc_notify b_free;
282 static __u16 misdn_cc_record_id;
284 static __s16 misdn_invoke_id;
286 static const char misdn_no_response_from_network[] =
"No response from network";
287 static const char misdn_cc_record_not_found[] =
"Call completion record not found";
290 #define MISDN_CC_RECORD_ID "MISDN_CC_RECORD_ID"
291 #define MISDN_CC_STATUS "MISDN_CC_STATUS"
292 #define MISDN_ERROR_MSG "MISDN_ERROR_MSG"
343 #define chan_list_ref(obj, debug) (ao2_t_ref((obj), +1, (debug)), (obj))
344 #define chan_list_unref(obj, debug) (ao2_t_ref((obj), -1, (debug)), NULL)
494 #if defined(AST_MISDN_ENHANCEMENTS)
498 struct misdn_cc_caller *peer;
606 for (r = robin, robin = NULL; r; r =
next) {
617 for (; iter; iter = iter->
next) {
618 if (!strcasecmp(iter->
group, group)) {
648 __attribute__((
format(printf, 3, 4)));
655 #define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
697 #if defined(AST_MISDN_ENHANCEMENTS)
698 static const char misdn_command_name[] =
"misdn_command";
699 static int misdn_command_exec(
struct ast_channel *chan,
const char *data);
728 for (list = cl_te; list; list = list->
next) {
745 for (tmp = cl_te; tmp; tmp = tmp->
next) {
746 if (tmp->
ast == ast) {
763 for (tmp = cl_te; tmp; tmp = tmp->
next) {
764 if (tmp->
ast && strcmp(tmp->
ast->
name, name) == 0) {
775 #if defined(AST_MISDN_ENHANCEMENTS)
799 static void misdn_cc_ds_destroy(
void *data)
801 struct misdn_cc_caller *cc_caller = data;
804 cc_caller->chan = NULL;
811 #if defined(AST_MISDN_ENHANCEMENTS)
823 static void *misdn_cc_ds_duplicate(
void *data)
825 struct misdn_cc_caller *cc_caller = data;
833 #if defined(AST_MISDN_ENHANCEMENTS)
836 .destroy = misdn_cc_ds_destroy,
837 .duplicate = misdn_cc_ds_duplicate,
841 #if defined(AST_MISDN_ENHANCEMENTS)
855 static void misdn_cc_set_peer_var(
struct misdn_cc_caller *peer,
const char *
var,
876 #if defined(AST_MISDN_ENHANCEMENTS)
881 static struct misdn_cc_caller *misdn_cc_caller_get(
struct ast_channel *chan)
884 struct misdn_cc_caller *cc_caller;
894 cc_caller = datastore->
data;
902 #if defined(AST_MISDN_ENHANCEMENTS)
914 static struct misdn_cc_record *misdn_cc_find_by_id(
long record_id)
916 struct misdn_cc_record *current;
919 if (current->record_id == record_id) {
929 #if defined(AST_MISDN_ENHANCEMENTS)
942 static struct misdn_cc_record *misdn_cc_find_by_linkage(
int port,
int linkage_id)
944 struct misdn_cc_record *current;
947 if (current->port == port
949 && current->mode.ptmp.linkage_id == linkage_id) {
959 #if defined(AST_MISDN_ENHANCEMENTS)
972 static struct misdn_cc_record *misdn_cc_find_by_invoke(
int port,
int invoke_id)
974 struct misdn_cc_record *current;
977 if (current->outstanding_message
978 && current->invoke_id == invoke_id
979 && current->port == port) {
989 #if defined(AST_MISDN_ENHANCEMENTS)
1002 static struct misdn_cc_record *misdn_cc_find_by_reference(
int port,
int reference_id)
1004 struct misdn_cc_record *current;
1007 if (current->activated
1008 && current->port == port
1010 && current->mode.ptmp.reference_id == reference_id) {
1020 #if defined(AST_MISDN_ENHANCEMENTS)
1032 static struct misdn_cc_record *misdn_cc_find_by_bc(
const struct misdn_bchannel *bc)
1034 struct misdn_cc_record *current;
1039 && current->mode.ptp.bc == bc) {
1052 #if defined(AST_MISDN_ENHANCEMENTS)
1063 static void misdn_cc_delete(
struct misdn_cc_record *doomed)
1065 struct misdn_cc_record *current;
1068 if (current == doomed) {
1080 #if defined(AST_MISDN_ENHANCEMENTS)
1089 static void misdn_cc_remove_old(
void)
1091 struct misdn_cc_record *current;
1096 if (MISDN_CC_RECORD_AGE_MAX < now - current->time_created) {
1097 if (current->ptp && current->mode.ptp.bc) {
1099 current->mode.ptp.bc->fac_out.Function = Fac_None;
1113 #if defined(AST_MISDN_ENHANCEMENTS)
1123 static long misdn_cc_record_id_new(
void)
1128 record_id = ++misdn_cc_record_id;
1129 first_id = record_id;
1130 while (misdn_cc_find_by_id(record_id)) {
1131 record_id = ++misdn_cc_record_id;
1132 if (record_id == first_id) {
1137 chan_misdn_log(0, 0,
" --> ERROR Too many call completion records!\n");
1147 #if defined(AST_MISDN_ENHANCEMENTS)
1157 static struct misdn_cc_record *misdn_cc_new(
void)
1159 struct misdn_cc_record *cc_record;
1162 misdn_cc_remove_old();
1164 cc_record =
ast_calloc(1,
sizeof(*cc_record));
1166 record_id = misdn_cc_record_id_new();
1167 if (record_id < 0) {
1173 cc_record->record_id = record_id;
1174 cc_record->port = -1;
1175 cc_record->invoke_id = ++misdn_invoke_id;
1176 cc_record->party_a_free = 1;
1177 cc_record->error_code = FacError_None;
1178 cc_record->reject_code = FacReject_None;
1179 cc_record->time_created = time(NULL);
1188 #if defined(AST_MISDN_ENHANCEMENTS)
1195 static void misdn_cc_destroy(
void)
1197 struct misdn_cc_record *current;
1206 #if defined(AST_MISDN_ENHANCEMENTS)
1213 static void misdn_cc_init(
void)
1215 misdn_cc_record_id = 0;
1219 #if defined(AST_MISDN_ENHANCEMENTS)
1229 static int misdn_cc_response_check(
void *data)
1232 struct misdn_cc_record *cc_record;
1235 cc_record = misdn_cc_find_by_id(*(
long *) data);
1237 if (cc_record->outstanding_message) {
1248 return not_responded;
1252 #if defined(AST_MISDN_ENHANCEMENTS)
1264 static void misdn_cc_response_wait(
struct ast_channel *chan,
int wait_seconds,
long record_id)
1268 for (count = 2 * MISDN_CC_REQUEST_WAIT_MAX; count--;) {
1278 #if defined(AST_MISDN_ENHANCEMENTS)
1287 static const char *misdn_to_str_reject_code(
enum FacRejectCode code)
1289 static const struct {
1290 enum FacRejectCode code;
1294 { FacReject_None,
"No reject occurred" },
1295 { FacReject_Unknown,
"Unknown reject code" },
1297 { FacReject_Gen_UnrecognizedComponent,
"General: Unrecognized Component" },
1298 { FacReject_Gen_MistypedComponent,
"General: Mistyped Component" },
1299 { FacReject_Gen_BadlyStructuredComponent,
"General: Badly Structured Component" },
1301 { FacReject_Inv_DuplicateInvocation,
"Invoke: Duplicate Invocation" },
1302 { FacReject_Inv_UnrecognizedOperation,
"Invoke: Unrecognized Operation" },
1303 { FacReject_Inv_MistypedArgument,
"Invoke: Mistyped Argument" },
1304 { FacReject_Inv_ResourceLimitation,
"Invoke: Resource Limitation" },
1305 { FacReject_Inv_InitiatorReleasing,
"Invoke: Initiator Releasing" },
1306 { FacReject_Inv_UnrecognizedLinkedID,
"Invoke: Unrecognized Linked ID" },
1307 { FacReject_Inv_LinkedResponseUnexpected,
"Invoke: Linked Response Unexpected" },
1308 { FacReject_Inv_UnexpectedChildOperation,
"Invoke: Unexpected Child Operation" },
1310 { FacReject_Res_UnrecognizedInvocation,
"Result: Unrecognized Invocation" },
1311 { FacReject_Res_ResultResponseUnexpected,
"Result: Result Response Unexpected" },
1312 { FacReject_Res_MistypedResult,
"Result: Mistyped Result" },
1314 { FacReject_Err_UnrecognizedInvocation,
"Error: Unrecognized Invocation" },
1315 { FacReject_Err_ErrorResponseUnexpected,
"Error: Error Response Unexpected" },
1316 { FacReject_Err_UnrecognizedError,
"Error: Unrecognized Error" },
1317 { FacReject_Err_UnexpectedError,
"Error: Unexpected Error" },
1318 { FacReject_Err_MistypedParameter,
"Error: Mistyped Parameter" },
1324 for (index = 0; index <
ARRAY_LEN(arr); ++index) {
1325 if (arr[index].code == code) {
1326 return arr[index].name;
1334 #if defined(AST_MISDN_ENHANCEMENTS)
1343 static const char *misdn_to_str_error_code(
enum FacErrorCode code)
1345 static const struct {
1346 enum FacErrorCode code;
1350 { FacError_None,
"No error occurred" },
1351 { FacError_Unknown,
"Unknown OID error code" },
1353 { FacError_Gen_NotSubscribed,
"General: Not Subscribed" },
1354 { FacError_Gen_NotAvailable,
"General: Not Available" },
1355 { FacError_Gen_NotImplemented,
"General: Not Implemented" },
1356 { FacError_Gen_InvalidServedUserNr,
"General: Invalid Served User Number" },
1357 { FacError_Gen_InvalidCallState,
"General: Invalid Call State" },
1358 { FacError_Gen_BasicServiceNotProvided,
"General: Basic Service Not Provided" },
1359 { FacError_Gen_NotIncomingCall,
"General: Not Incoming Call" },
1360 { FacError_Gen_SupplementaryServiceInteractionNotAllowed,
"General: Supplementary Service Interaction Not Allowed" },
1361 { FacError_Gen_ResourceUnavailable,
"General: Resource Unavailable" },
1363 { FacError_Div_InvalidDivertedToNr,
"Diversion: Invalid Diverted To Number" },
1364 { FacError_Div_SpecialServiceNr,
"Diversion: Special Service Number" },
1365 { FacError_Div_DiversionToServedUserNr,
"Diversion: Diversion To Served User Number" },
1366 { FacError_Div_IncomingCallAccepted,
"Diversion: Incoming Call Accepted" },
1367 { FacError_Div_NumberOfDiversionsExceeded,
"Diversion: Number Of Diversions Exceeded" },
1368 { FacError_Div_NotActivated,
"Diversion: Not Activated" },
1369 { FacError_Div_RequestAlreadyAccepted,
"Diversion: Request Already Accepted" },
1371 { FacError_AOC_NoChargingInfoAvailable,
"AOC: No Charging Info Available" },
1373 { FacError_CCBS_InvalidCallLinkageID,
"CCBS: Invalid Call Linkage ID" },
1374 { FacError_CCBS_InvalidCCBSReference,
"CCBS: Invalid CCBS Reference" },
1375 { FacError_CCBS_LongTermDenial,
"CCBS: Long Term Denial" },
1376 { FacError_CCBS_ShortTermDenial,
"CCBS: Short Term Denial" },
1377 { FacError_CCBS_IsAlreadyActivated,
"CCBS: Is Already Activated" },
1378 { FacError_CCBS_AlreadyAccepted,
"CCBS: Already Accepted" },
1379 { FacError_CCBS_OutgoingCCBSQueueFull,
"CCBS: Outgoing CCBS Queue Full" },
1380 { FacError_CCBS_CallFailureReasonNotBusy,
"CCBS: Call Failure Reason Not Busy" },
1381 { FacError_CCBS_NotReadyForCall,
"CCBS: Not Ready For Call" },
1383 { FacError_CCBS_T_LongTermDenial,
"CCBS-T: Long Term Denial" },
1384 { FacError_CCBS_T_ShortTermDenial,
"CCBS-T: Short Term Denial" },
1386 { FacError_ECT_LinkIdNotAssignedByNetwork,
"ECT: Link ID Not Assigned By Network" },
1392 for (index = 0; index <
ARRAY_LEN(arr); ++index) {
1393 if (arr[index].code == code) {
1394 return arr[index].name;
1402 #if defined(AST_MISDN_ENHANCEMENTS)
1413 unsigned diversion_reason;
1417 diversion_reason = 1;
1420 diversion_reason = 2;
1423 diversion_reason = 3;
1426 diversion_reason = 0;
1430 return diversion_reason;
1434 #if defined(AST_MISDN_ENHANCEMENTS)
1447 switch (diversion_reason) {
1466 #if defined(AST_MISDN_ENHANCEMENTS)
1476 static unsigned misdn_to_PresentedNumberUnscreened_type(
int presentation,
int number_present)
1480 switch (presentation) {
1482 if (number_present) {
1489 if (number_present) {
1504 #if defined(AST_MISDN_ENHANCEMENTS)
1513 static int PresentedNumberUnscreened_to_misdn_pres(
unsigned type)
1533 return presentation;
1537 #if defined(AST_MISDN_ENHANCEMENTS)
1548 unsigned party_plan;
1550 switch (number_plan) {
1581 #if defined(AST_MISDN_ENHANCEMENTS)
1594 switch (party_plan) {
1620 #if defined(AST_MISDN_ENHANCEMENTS)
1664 #if defined(AST_MISDN_ENHANCEMENTS)
1673 static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_public(
unsigned party_ton)
1677 switch (party_ton) {
1708 #if defined(AST_MISDN_ENHANCEMENTS)
1752 #if defined(AST_MISDN_ENHANCEMENTS)
1761 static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_private(
unsigned party_ton)
1765 switch (party_ton) {
1808 switch (number_type) {
1815 str =
"International";
1823 str =
"Network Specific";
1831 str =
"Abbreviated";
1848 int ast_number_type;
1850 switch (number_type) {
1877 return ast_number_type;
1892 switch ((ast_number_type >> 4) & 0x07) {
1934 switch (number_plan) {
1974 int ast_number_plan;
1976 switch (number_plan) {
2003 return ast_number_plan;
2018 switch (ast_number_plan & 0x0F) {
2060 switch (presentation) {
2070 str =
"Unavailable";
2091 switch (presentation) {
2106 return presentation;
2134 return presentation;
2149 switch (screening) {
2155 str =
"Passed Screen";
2159 str =
"Failed Screen";
2163 str =
"Network Number";
2184 switch (screening) {
2250 static const struct misdn_reasons {
2253 } misdn_reason_table[] = {
2270 for (index = 0; index <
ARRAY_LEN(misdn_reason_table); ++index) {
2271 if (misdn_reason_table[index].ast == ast) {
2272 return misdn_reason_table[index].q931;
2349 for (index = 0; index <
ARRAY_LEN(allowed_bearers_array); ++index) {
2350 if (allowed_bearers_array[index].cap == cap) {
2351 return allowed_bearers_array[index].
display;
2355 return "Unknown Bearer";
2358 #if defined(AST_MISDN_ENHANCEMENTS)
2368 static void misdn_PartyNumber_fill(
struct FacPartyNumber *party,
const struct misdn_party_id *
id)
2371 party->LengthOfNumber = strlen((
char *) party->Number);
2372 party->Type = misdn_to_PartyNumber_plan(id->
number_plan);
2373 switch (party->Type) {
2375 party->TypeOfNumber = misdn_to_PartyNumber_ton_public(id->
number_type);
2378 party->TypeOfNumber = misdn_to_PartyNumber_ton_private(id->
number_type);
2381 party->TypeOfNumber = 0;
2387 #if defined(AST_MISDN_ENHANCEMENTS)
2397 static void misdn_PartyNumber_extract(
struct misdn_party_id *
id,
const struct FacPartyNumber *party)
2399 if (party->LengthOfNumber) {
2401 id->number_plan = PartyNumber_to_misdn_plan(party->Type);
2402 switch (party->Type) {
2404 id->number_type = PartyNumber_to_misdn_ton_public(party->TypeOfNumber);
2407 id->number_type = PartyNumber_to_misdn_ton_private(party->TypeOfNumber);
2422 #if defined(AST_MISDN_ENHANCEMENTS)
2432 static void misdn_Address_fill(
struct FacAddress *Address,
const struct misdn_party_id *
id)
2434 misdn_PartyNumber_fill(&Address->Party,
id);
2437 Address->Subaddress.Length = 0;
2441 #if defined(AST_MISDN_ENHANCEMENTS)
2451 static void misdn_PresentedNumberUnscreened_fill(
struct FacPresentedNumberUnscreened *presented,
const struct misdn_party_id *
id)
2453 presented->Type = misdn_to_PresentedNumberUnscreened_type(id->
presentation, id->
number[0] ? 1 : 0);
2454 misdn_PartyNumber_fill(&presented->Unscreened,
id);
2458 #if defined(AST_MISDN_ENHANCEMENTS)
2468 static void misdn_PresentedNumberUnscreened_extract(
struct misdn_party_id *
id,
const struct FacPresentedNumberUnscreened *presented)
2470 id->presentation = PresentedNumberUnscreened_to_misdn_pres(presented->Type);
2472 switch (presented->Type) {
2475 misdn_PartyNumber_extract(
id, &presented->Unscreened);
2489 #if defined(AST_MISDN_ENHANCEMENTS)
2490 static const char Level_Spacing[] =
" ";
2493 #if defined(AST_MISDN_ENHANCEMENTS)
2494 static void print_facility_PartyNumber(
unsigned Level,
const struct FacPartyNumber *Party,
const struct misdn_bchannel *bc)
2496 if (Party->LengthOfNumber) {
2497 const char *Spacing;
2499 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2501 Spacing, Party->Type);
2502 switch (Party->Type) {
2505 Spacing, Party->Number);
2509 Spacing, Party->TypeOfNumber, Party->Number);
2513 Spacing, Party->Number);
2517 Spacing, Party->Number);
2521 Spacing, Party->Number);
2525 Spacing, Party->TypeOfNumber, Party->Number);
2529 Spacing, Party->Number);
2538 #if defined(AST_MISDN_ENHANCEMENTS)
2539 static void print_facility_Subaddress(
unsigned Level,
const struct FacPartySubaddress *Subaddress,
const struct misdn_bchannel *bc)
2541 if (Subaddress->Length) {
2542 const char *Spacing;
2544 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2546 Spacing, Subaddress->Type);
2547 switch (Subaddress->Type) {
2549 if (Subaddress->u.UserSpecified.OddCountPresent) {
2551 Spacing, Subaddress->u.UserSpecified.OddCount, Subaddress->Length);
2554 Spacing, Subaddress->u.UserSpecified.Information);
2559 Spacing, Subaddress->u.Nsap);
2568 #if defined(AST_MISDN_ENHANCEMENTS)
2569 static void print_facility_Address(
unsigned Level,
const struct FacAddress *Address,
const struct misdn_bchannel *bc)
2571 print_facility_PartyNumber(Level, &Address->Party, bc);
2572 print_facility_Subaddress(Level, &Address->Subaddress, bc);
2576 #if defined(AST_MISDN_ENHANCEMENTS)
2577 static void print_facility_PresentedNumberUnscreened(
unsigned Level,
const struct FacPresentedNumberUnscreened *Presented,
const struct misdn_bchannel *bc)
2579 const char *Spacing;
2581 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2582 chan_misdn_log(1, bc->
port,
" -->%s Unscreened Type:%d\n", Spacing, Presented->Type);
2583 switch (Presented->Type) {
2586 print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
2596 print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
2604 #if defined(AST_MISDN_ENHANCEMENTS)
2605 static void print_facility_AddressScreened(
unsigned Level,
const struct FacAddressScreened *Address,
const struct misdn_bchannel *bc)
2607 const char *Spacing;
2609 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2610 chan_misdn_log(1, bc->
port,
" -->%s ScreeningIndicator:%d\n", Spacing, Address->ScreeningIndicator);
2611 print_facility_PartyNumber(Level, &Address->Party, bc);
2612 print_facility_Subaddress(Level, &Address->Subaddress, bc);
2616 #if defined(AST_MISDN_ENHANCEMENTS)
2617 static void print_facility_PresentedAddressScreened(
unsigned Level,
const struct FacPresentedAddressScreened *Presented,
const struct misdn_bchannel *bc)
2619 const char *Spacing;
2621 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2623 switch (Presented->Type) {
2626 print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
2636 print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
2644 #if defined(AST_MISDN_ENHANCEMENTS)
2645 static void print_facility_Q931_Bc_Hlc_Llc(
unsigned Level,
const struct Q931_Bc_Hlc_Llc *Q931ie,
const struct misdn_bchannel *bc)
2647 const char *Spacing;
2649 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2651 if (Q931ie->Bc.Length) {
2654 if (Q931ie->Hlc.Length) {
2657 if (Q931ie->Llc.Length) {
2663 #if defined(AST_MISDN_ENHANCEMENTS)
2664 static void print_facility_Q931_Bc_Hlc_Llc_Uu(
unsigned Level,
const struct Q931_Bc_Hlc_Llc_Uu *Q931ie,
const struct misdn_bchannel *bc)
2666 const char *Spacing;
2668 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2670 if (Q931ie->Bc.Length) {
2673 if (Q931ie->Hlc.Length) {
2676 if (Q931ie->Llc.Length) {
2679 if (Q931ie->UserInfo.Length) {
2680 chan_misdn_log(1, bc->
port,
" -->%s UserInfo Len:%d\n", Spacing, Q931ie->UserInfo.Length);
2685 #if defined(AST_MISDN_ENHANCEMENTS)
2686 static void print_facility_CallInformation(
unsigned Level,
const struct FacCallInformation *CallInfo,
const struct misdn_bchannel *bc)
2688 const char *Spacing;
2690 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2692 Spacing, CallInfo->CCBSReference);
2694 print_facility_Address(Level + 1, &CallInfo->AddressOfB, bc);
2695 print_facility_Q931_Bc_Hlc_Llc(Level, &CallInfo->Q931ie, bc);
2696 if (CallInfo->SubaddressOfA.Length) {
2698 print_facility_Subaddress(Level + 1, &CallInfo->SubaddressOfA, bc);
2703 #if defined(AST_MISDN_ENHANCEMENTS)
2704 static void print_facility_ServedUserNr(
unsigned Level,
const struct FacPartyNumber *Party,
const struct misdn_bchannel *bc)
2706 const char *Spacing;
2708 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2709 if (Party->LengthOfNumber) {
2710 print_facility_PartyNumber(Level, Party, bc);
2717 #if defined(AST_MISDN_ENHANCEMENTS)
2718 static void print_facility_IntResult(
unsigned Level,
const struct FacForwardingRecord *ForwardingRecord,
const struct misdn_bchannel *bc)
2720 const char *Spacing;
2722 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2725 ForwardingRecord->Procedure,
2726 ForwardingRecord->BasicService);
2728 print_facility_Address(Level + 1, &ForwardingRecord->ForwardedTo, bc);
2730 print_facility_ServedUserNr(Level + 1, &ForwardingRecord->ServedUser, bc);
2736 #if defined(AST_MISDN_ENHANCEMENTS)
2740 switch (fac->Function) {
2741 #if defined(AST_MISDN_ENHANCEMENTS)
2742 case Fac_ActivationDiversion:
2744 fac->u.ActivationDiversion.InvokeID);
2745 switch (fac->u.ActivationDiversion.ComponentType) {
2746 case FacComponent_Invoke:
2748 fac->u.ActivationDiversion.Component.Invoke.Procedure,
2749 fac->u.ActivationDiversion.Component.Invoke.BasicService);
2751 print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc);
2753 print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc);
2755 case FacComponent_Result:
2762 case Fac_DeactivationDiversion:
2764 fac->u.DeactivationDiversion.InvokeID);
2765 switch (fac->u.DeactivationDiversion.ComponentType) {
2766 case FacComponent_Invoke:
2768 fac->u.DeactivationDiversion.Component.Invoke.Procedure,
2769 fac->u.DeactivationDiversion.Component.Invoke.BasicService);
2771 print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc);
2773 case FacComponent_Result:
2780 case Fac_ActivationStatusNotificationDiv:
2781 chan_misdn_log(1, bc->
port,
" --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2782 fac->u.ActivationStatusNotificationDiv.InvokeID,
2783 fac->u.ActivationStatusNotificationDiv.Procedure,
2784 fac->u.ActivationStatusNotificationDiv.BasicService);
2786 print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc);
2788 print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc);
2790 case Fac_DeactivationStatusNotificationDiv:
2791 chan_misdn_log(1, bc->
port,
" --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2792 fac->u.DeactivationStatusNotificationDiv.InvokeID,
2793 fac->u.DeactivationStatusNotificationDiv.Procedure,
2794 fac->u.DeactivationStatusNotificationDiv.BasicService);
2796 print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc);
2798 case Fac_InterrogationDiversion:
2800 fac->u.InterrogationDiversion.InvokeID);
2801 switch (fac->u.InterrogationDiversion.ComponentType) {
2802 case FacComponent_Invoke:
2804 fac->u.InterrogationDiversion.Component.Invoke.Procedure,
2805 fac->u.InterrogationDiversion.Component.Invoke.BasicService);
2807 print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc);
2809 case FacComponent_Result:
2811 if (fac->u.InterrogationDiversion.Component.Result.NumRecords) {
2812 for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) {
2814 print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc);
2822 case Fac_DiversionInformation:
2823 chan_misdn_log(1, bc->
port,
" --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n",
2824 fac->u.DiversionInformation.InvokeID,
2825 fac->u.DiversionInformation.DiversionReason,
2826 fac->u.DiversionInformation.BasicService);
2827 if (fac->u.DiversionInformation.ServedUserSubaddress.Length) {
2829 print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc);
2831 if (fac->u.DiversionInformation.CallingAddressPresent) {
2833 print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc);
2835 if (fac->u.DiversionInformation.OriginalCalledPresent) {
2837 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc);
2839 if (fac->u.DiversionInformation.LastDivertingPresent) {
2841 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc);
2843 if (fac->u.DiversionInformation.LastDivertingReasonPresent) {
2844 chan_misdn_log(1, bc->
port,
" --> LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason);
2846 if (fac->u.DiversionInformation.UserInfo.Length) {
2847 chan_misdn_log(1, bc->
port,
" --> UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length);
2850 case Fac_CallDeflection:
2852 fac->u.CallDeflection.InvokeID);
2853 switch (fac->u.CallDeflection.ComponentType) {
2854 case FacComponent_Invoke:
2856 if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
2858 fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser);
2861 print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc);
2863 case FacComponent_Result:
2870 case Fac_CallRerouteing:
2872 fac->u.CallRerouteing.InvokeID);
2873 switch (fac->u.CallRerouteing.ComponentType) {
2874 case FacComponent_Invoke:
2876 fac->u.CallRerouteing.Component.Invoke.ReroutingReason,
2877 fac->u.CallRerouteing.Component.Invoke.ReroutingCounter);
2879 print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc);
2880 print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc);
2882 print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc);
2884 fac->u.CallRerouteing.Component.Invoke.SubscriptionOption);
2885 if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) {
2887 print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc);
2890 case FacComponent_Result:
2897 case Fac_InterrogateServedUserNumbers:
2899 fac->u.InterrogateServedUserNumbers.InvokeID);
2900 switch (fac->u.InterrogateServedUserNumbers.ComponentType) {
2901 case FacComponent_Invoke:
2904 case FacComponent_Result:
2906 if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) {
2907 for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) {
2909 print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc);
2917 case Fac_DivertingLegInformation1:
2918 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n",
2919 fac->u.DivertingLegInformation1.InvokeID,
2920 fac->u.DivertingLegInformation1.DiversionReason,
2921 fac->u.DivertingLegInformation1.SubscriptionOption);
2922 if (fac->u.DivertingLegInformation1.DivertedToPresent) {
2924 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc);
2927 case Fac_DivertingLegInformation2:
2928 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n",
2929 fac->u.DivertingLegInformation2.InvokeID,
2930 fac->u.DivertingLegInformation2.DiversionReason,
2931 fac->u.DivertingLegInformation2.DiversionCounter);
2932 if (fac->u.DivertingLegInformation2.DivertingPresent) {
2934 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc);
2936 if (fac->u.DivertingLegInformation2.OriginalCalledPresent) {
2938 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc);
2941 case Fac_DivertingLegInformation3:
2942 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n",
2943 fac->u.DivertingLegInformation3.InvokeID,
2944 fac->u.DivertingLegInformation3.PresentationAllowedIndicator);
2950 chan_misdn_log(1, bc->
port,
" --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
2951 fac->u.CDeflection.PresentationAllowed ?
"yes" :
"no");
2954 case Fac_AOCDCurrency:
2955 if (fac->u.AOCDcur.chargeNotAvailable) {
2957 }
else if (fac->u.AOCDcur.freeOfCharge) {
2959 }
else if (fac->u.AOCDchu.billingId >= 0) {
2960 chan_misdn_log(1, bc->
port,
" --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
2961 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2962 (fac->u.AOCDcur.typeOfChargingInfo == 0) ?
"subTotal" :
"total", fac->u.AOCDcur.billingId);
2964 chan_misdn_log(1, bc->
port,
" --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
2965 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2966 (fac->u.AOCDcur.typeOfChargingInfo == 0) ?
"subTotal" :
"total");
2969 case Fac_AOCDChargingUnit:
2970 if (fac->u.AOCDchu.chargeNotAvailable) {
2972 }
else if (fac->u.AOCDchu.freeOfCharge) {
2974 }
else if (fac->u.AOCDchu.billingId >= 0) {
2975 chan_misdn_log(1, bc->
port,
" --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
2976 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ?
"subTotal" :
"total", fac->u.AOCDchu.billingId);
2978 chan_misdn_log(1, bc->
port,
" --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
2979 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ?
"subTotal" :
"total");
2982 #if defined(AST_MISDN_ENHANCEMENTS)
2985 fac->u.ERROR.invokeId, fac->u.ERROR.errorValue);
2989 fac->u.RESULT.InvokeID);
2992 if (fac->u.REJECT.InvokeIDPresent) {
2994 fac->u.REJECT.InvokeID, fac->u.REJECT.Code);
2997 fac->u.REJECT.Code);
3000 case Fac_EctExecute:
3002 fac->u.EctExecute.InvokeID);
3004 case Fac_ExplicitEctExecute:
3006 fac->u.ExplicitEctExecute.InvokeID,
3007 fac->u.ExplicitEctExecute.LinkID);
3009 case Fac_RequestSubaddress:
3011 fac->u.RequestSubaddress.InvokeID);
3013 case Fac_SubaddressTransfer:
3015 fac->u.SubaddressTransfer.InvokeID);
3016 print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc);
3018 case Fac_EctLinkIdRequest:
3020 fac->u.EctLinkIdRequest.InvokeID);
3021 switch (fac->u.EctLinkIdRequest.ComponentType) {
3022 case FacComponent_Invoke:
3025 case FacComponent_Result:
3027 fac->u.EctLinkIdRequest.Component.Result.LinkID);
3035 fac->u.EctInform.InvokeID,
3036 fac->u.EctInform.Status);
3037 if (fac->u.EctInform.RedirectionPresent) {
3039 print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc);
3042 case Fac_EctLoopTest:
3044 fac->u.EctLoopTest.InvokeID);
3045 switch (fac->u.EctLoopTest.ComponentType) {
3046 case FacComponent_Invoke:
3048 fac->u.EctLoopTest.Component.Invoke.CallTransferID);
3050 case FacComponent_Result:
3052 fac->u.EctLoopTest.Component.Result.LoopResult);
3058 case Fac_StatusRequest:
3060 fac->u.StatusRequest.InvokeID);
3061 switch (fac->u.StatusRequest.ComponentType) {
3062 case FacComponent_Invoke:
3064 fac->u.StatusRequest.Component.Invoke.CompatibilityMode);
3066 case FacComponent_Result:
3068 fac->u.StatusRequest.Component.Result.Status);
3074 case Fac_CallInfoRetain:
3076 fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID);
3078 case Fac_CCBSDeactivate:
3080 fac->u.CCBSDeactivate.InvokeID);
3081 switch (fac->u.CCBSDeactivate.ComponentType) {
3082 case FacComponent_Invoke:
3084 fac->u.CCBSDeactivate.Component.Invoke.CCBSReference);
3086 case FacComponent_Result:
3094 chan_misdn_log(1, bc->
port,
" --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n",
3095 fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
3096 fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
3098 print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
3099 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
3101 case Fac_CCBSRemoteUserFree:
3102 chan_misdn_log(1, bc->
port,
" --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3103 fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
3104 fac->u.CCBSRemoteUserFree.RecallMode);
3106 print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
3107 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
3111 fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference);
3113 case Fac_CCBSStatusRequest:
3115 fac->u.CCBSStatusRequest.InvokeID);
3116 switch (fac->u.CCBSStatusRequest.ComponentType) {
3117 case FacComponent_Invoke:
3119 fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
3120 fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
3121 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
3123 case FacComponent_Result:
3125 fac->u.CCBSStatusRequest.Component.Result.Free);
3132 chan_misdn_log(1, bc->
port,
" --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3133 fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
3134 fac->u.CCBSBFree.RecallMode);
3136 print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
3137 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
3139 case Fac_EraseCallLinkageID:
3141 fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID);
3143 case Fac_CCBSStopAlerting:
3144 chan_misdn_log(1, bc->
port,
" --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n",
3145 fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference);
3147 case Fac_CCBSRequest:
3149 fac->u.CCBSRequest.InvokeID);
3150 switch (fac->u.CCBSRequest.ComponentType) {
3151 case FacComponent_Invoke:
3153 fac->u.CCBSRequest.Component.Invoke.CallLinkageID);
3155 case FacComponent_Result:
3157 fac->u.CCBSRequest.Component.Result.CCBSReference,
3158 fac->u.CCBSRequest.Component.Result.RecallMode);
3164 case Fac_CCBSInterrogate:
3166 fac->u.CCBSInterrogate.InvokeID);
3167 switch (fac->u.CCBSInterrogate.ComponentType) {
3168 case FacComponent_Invoke:
3170 if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) {
3172 fac->u.CCBSInterrogate.Component.Invoke.CCBSReference);
3174 if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3176 print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
3179 case FacComponent_Result:
3181 fac->u.CCBSInterrogate.Component.Result.RecallMode);
3182 if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
3183 for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
3185 print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
3193 case Fac_CCNRRequest:
3195 fac->u.CCNRRequest.InvokeID);
3196 switch (fac->u.CCNRRequest.ComponentType) {
3197 case FacComponent_Invoke:
3199 fac->u.CCNRRequest.Component.Invoke.CallLinkageID);
3201 case FacComponent_Result:
3203 fac->u.CCNRRequest.Component.Result.CCBSReference,
3204 fac->u.CCNRRequest.Component.Result.RecallMode);
3210 case Fac_CCNRInterrogate:
3212 fac->u.CCNRInterrogate.InvokeID);
3213 switch (fac->u.CCNRInterrogate.ComponentType) {
3214 case FacComponent_Invoke:
3216 if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) {
3218 fac->u.CCNRInterrogate.Component.Invoke.CCBSReference);
3220 if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3222 print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
3225 case FacComponent_Result:
3227 fac->u.CCNRInterrogate.Component.Result.RecallMode);
3228 if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
3229 for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
3231 print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
3239 case Fac_CCBS_T_Call:
3241 fac->u.CCBS_T_Call.InvokeID);
3243 case Fac_CCBS_T_Suspend:
3245 fac->u.CCBS_T_Suspend.InvokeID);
3247 case Fac_CCBS_T_Resume:
3249 fac->u.CCBS_T_Resume.InvokeID);
3251 case Fac_CCBS_T_RemoteUserFree:
3253 fac->u.CCBS_T_RemoteUserFree.InvokeID);
3255 case Fac_CCBS_T_Available:
3257 fac->u.CCBS_T_Available.InvokeID);
3259 case Fac_CCBS_T_Request:
3261 fac->u.CCBS_T_Request.InvokeID);
3262 switch (fac->u.CCBS_T_Request.ComponentType) {
3263 case FacComponent_Invoke:
3266 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
3267 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
3268 if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
3271 if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3273 fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
3275 if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3277 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
3280 case FacComponent_Result:
3282 fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
3288 case Fac_CCNR_T_Request:
3290 fac->u.CCNR_T_Request.InvokeID);
3291 switch (fac->u.CCNR_T_Request.ComponentType) {
3292 case FacComponent_Invoke:
3295 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
3296 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
3297 if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
3300 if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3302 fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
3304 if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3306 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
3309 case FacComponent_Result:
3311 fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
3360 len_prefix = strlen(str_prefix);
3365 len_main = strlen(str_main);
3366 len_total = len_prefix + len_main;
3367 if (size <= len_total) {
3369 len_over = len_total + 1 - size;
3370 if (len_over <= len_main) {
3371 len_main -= len_over;
3373 len_over -= len_main;
3375 len_prefix -= len_over;
3379 memmove(str_main + len_prefix, str_main, len_main);
3381 memcpy(str_main, str_prefix, len_prefix);
3382 str_main[len_prefix + len_main] =
'\0';
3402 switch (number_type) {
3425 misdn_cfg_get(port, type_prefix, num_prefix,
sizeof(num_prefix));
3446 case Fac_AOCDCurrency:
3458 if (bc->
AOCD.
currency.billingId >= 0 && snprintf(buf,
sizeof(buf),
"%d", bc->
AOCD.
currency.billingId) <
sizeof(buf)) {
3465 case Fac_AOCDChargingUnit:
3475 if (snprintf(buf,
sizeof(buf),
"%d", bc->
AOCD.
chargingUnit.recordedUnits) <
sizeof(buf)) {
3500 struct sigaction sa;
3503 sa.sa_flags = SA_NODEFER;
3504 sigemptyset(&sa.sa_mask);
3505 sigaddset(&sa.sa_mask, SIGUSR1);
3506 sigaction(SIGUSR1, &sa, NULL);
3508 sem_post((sem_t *)data);
3515 if (poll(NULL, 0, wait) < 0) {
3528 if (sem_init(&blocker, 0, 0)) {
3529 perror(
"chan_misdn: Failed to initialize semaphore!");
3538 while (sem_wait(&blocker) && --i) {
3540 sem_destroy(&blocker);
3547 if (pthread_cancel(misdn_tasks_thread) == 0) {
3548 cb_log(4, 0,
"Joining misdn_tasks thread\n");
3549 pthread_join(misdn_tasks_thread, NULL);
3557 pthread_kill(misdn_tasks_thread, SIGUSR1);
3590 const int *data = vdata;
3599 struct timeval tv_end, tv_now;
3637 goto misdn_overlap_dial_task_disconnect;
3640 misdn_overlap_dial_task_disconnect:
3652 static const char *
const dtmf_tones[] = {
3654 "!941+1336/100,!0/100",
3655 "!697+1209/100,!0/100",
3656 "!697+1336/100,!0/100",
3657 "!697+1477/100,!0/100",
3658 "!770+1209/100,!0/100",
3659 "!770+1336/100,!0/100",
3660 "!770+1477/100,!0/100",
3661 "!852+1209/100,!0/100",
3662 "!852+1336/100,!0/100",
3663 "!852+1477/100,!0/100",
3664 "!697+1633/100,!0/100",
3665 "!770+1633/100,!0/100",
3666 "!852+1633/100,!0/100",
3667 "!941+1633/100,!0/100",
3668 "!941+1209/100,!0/100",
3669 "!941+1477/100,!0/100",
3674 if (digit >=
'0' && digit <=
'9') {
3676 }
else if (digit >=
'A' && digit <=
'D') {
3678 }
else if (digit ==
'*') {
3680 }
else if (digit ==
'#') {
3684 ast_debug(1,
"Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->
name);
3695 e->
command =
"misdn set debug [on|off]";
3697 "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n"
3698 " Set the debug level of the mISDN channel.\n";
3708 if (!strcasecmp(a->
argv[3],
"on")) {
3710 }
else if (!strcasecmp(a->
argv[3],
"off")) {
3712 }
else if (isdigit(a->
argv[3][0])) {
3713 level = atoi(a->
argv[3]);
3725 if (strncasecmp(a->
argv[4],
"only", strlen(a->
argv[4]))) {
3733 misdn_debug[i] = level;
3734 misdn_debug_only[i] = only;
3736 ast_cli(a->
fd,
"changing debug level for all ports to %d%s\n", misdn_debug[0], only ?
" (only)" :
"");
3743 if (strncasecmp(a->
argv[4],
"port", strlen(a->
argv[4])))
3745 port = atoi(a->
argv[5]);
3746 if (port <= 0 || port > max_ports) {
3747 switch (max_ports) {
3749 ast_cli(a->
fd,
"port number not valid! no ports available so you won't get lucky with any number here...\n");
3752 ast_cli(a->
fd,
"port number not valid! only port 1 is available.\n");
3755 ast_cli(a->
fd,
"port number not valid! only ports 1 to %d are available.\n", max_ports);
3760 if (strncasecmp(a->
argv[6],
"only", strlen(a->
argv[6]))) {
3763 misdn_debug_only[port] = 1;
3766 misdn_debug_only[port] = 0;
3768 misdn_debug[port] = level;
3769 ast_cli(a->
fd,
"changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ?
" (only)" :
"", port);
3780 e->
command =
"misdn set crypt debug";
3782 "Usage: misdn set crypt debug <level>\n"
3783 " Set the crypt debug level of the mISDN channel. Level\n"
3784 " must be 1 or 2.\n";
3803 e->
command =
"misdn port block";
3805 "Usage: misdn port block <port>\n"
3806 " Block the specified port by <port>.\n";
3825 e->
command =
"misdn port unblock";
3827 "Usage: misdn port unblock <port>\n"
3828 " Unblock the port specified by <port>.\n";
3847 e->
command =
"misdn restart port";
3849 "Usage: misdn restart port <port>\n"
3850 " Restart the given port.\n";
3869 e->
command =
"misdn restart pid";
3871 "Usage: misdn restart pid <pid>\n"
3872 " Restart the given pid\n";
3893 "Usage: misdn port up <port>\n"
3894 " Try to establish L1 on the given port.\n";
3913 e->
command =
"misdn port down";
3915 "Usage: misdn port down <port>\n"
3916 " Try to deactivate the L1 on the given port.\n";
3950 ast_cli(fd,
"[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
3952 ast_cli(fd,
"[%s] %s\n\t%s\n", section, name, desc);
3966 e->
command =
"misdn show config";
3968 "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
3969 " Use 0 for <port> to only print the general config.\n";
3976 if (!strcmp(a->
argv[3],
"description")) {
3987 }
else if (!strcmp(a->
argv[3],
"descriptions")) {
3988 if ((a->
argc == 4) || ((a->
argc == 5) && !strcmp(a->
argv[4],
"general"))) {
3995 if ((a->
argc == 4) || ((a->
argc == 5) && !strcmp(a->
argv[4],
"ports"))) {
4003 }
else if (!sscanf(a->
argv[3],
"%5d", &onlyport) || onlyport < 0) {
4009 if (a->
argc == 3 || onlyport == 0) {
4010 ast_cli(a->
fd,
"mISDN General-Config:\n");
4013 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4025 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4033 ast_cli(a->
fd,
"[PORT %d]\n", onlyport);
4036 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4040 ast_cli(a->
fd,
"Port %d is not active!\n", onlyport);
4074 static char state[8];
4080 for (i = 0; i <
ARRAY_LEN(state_array); i++) {
4081 if (state_array[i].state == p->
state) {
4082 return state_array[i].
txt;
4086 snprintf(state,
sizeof(state),
"%d", p->
state) ;
4096 if (!g_config_initialized) {
4108 misdn_debug[i] = cfg_debug;
4109 misdn_debug_only[i] = 0;
4119 "Usage: misdn reload\n"
4120 " Reload internal mISDN config, read from the config\n"
4131 ast_cli(a->
fd,
"Reloading mISDN configuration\n");
4141 "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n"
4142 " --> caller:\"%s\" <%s>\n"
4143 " --> redirecting-from:\"%s\" <%s>\n"
4144 " --> redirecting-to:\"%s\" <%s>\n"
4145 " --> context:%s state:%s\n",
4149 bc->
nt ?
"NT" :
"TE",
4151 ast ? ast->
exten :
"",
4162 if (misdn_debug[bc->
port] > 0) {
4164 " --> astname: %s\n"
4165 " --> ch_l3id: %x\n"
4166 " --> ch_addr: %x\n"
4167 " --> bc_addr: %x\n"
4168 " --> bc_l3id: %x\n"
4169 " --> display: %s\n"
4170 " --> activated: %d\n"
4172 " --> capability: %s\n"
4174 " --> pipeline: %s\n"
4176 " --> echo_cancel: %d\n"
4178 " --> notone : rx %d tx:%d\n"
4179 " --> bc_hold: %d\n",
4180 ast ? ast->
name :
"",
4205 e->
command =
"misdn show channels";
4207 "Usage: misdn show channels\n"
4208 " Show the internal mISDN channel list\n";
4218 ast_cli(a->
fd,
"Channel List: %p\n", cl_te);
4227 for (help = cl_te; help; help = help->
next) {
4232 ast_cli(a->
fd,
"chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->
l3id);
4235 ast_cli(a->
fd,
"bc with pid:%d has no Ast Leg\n", bc->
pid);
4238 if (misdn_debug[0] > 2) {
4239 ast_cli(a->
fd,
"Bc:%p Ast:%p\n", bc, ast);
4245 ast_cli(a->
fd,
"ITS A HELD CALL BC:\n");
4248 " --> caller:\"%s\" <%s>\n"
4249 " --> hold_port: %d\n"
4250 " --> hold_channel: %d\n",
4259 ast_cli(a->
fd,
"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
4278 e->
command =
"misdn show channel";
4280 "Usage: misdn show channel <channel>\n"
4281 " Show an internal mISDN channel\n.";
4292 for (help = cl_te; help; help = help->
next) {
4297 if (!strcasecmp(ast->
name, a->
argv[3])) {
4312 e->
command =
"misdn set tics";
4314 "Usage: misdn set tics <value>\n";
4325 MAXTICS = atoi(a->
argv[3]);
4336 e->
command =
"misdn show stacks";
4338 "Usage: misdn show stacks\n"
4339 " Show internal mISDN stack_list.\n";
4355 ast_cli(a->
fd,
" %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ?
"(only)" :
"");
4367 e->
command =
"misdn show ports stats";
4369 "Usage: misdn show ports stats\n"
4370 " Show mISDNs channel's call statistics per port.\n";
4380 ast_cli(a->
fd,
"Port\tin_calls\tout_calls\n");
4383 ast_cli(a->
fd,
"%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
4397 e->
command =
"misdn show port";
4399 "Usage: misdn show port <port>\n"
4400 " Show detailed information for given port.\n";
4410 port = atoi(a->
argv[3]);
4414 ast_cli(a->
fd,
" %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ?
"(only)" :
"");
4419 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
4420 static const struct FacParm Fac_Msgs[] = {
4422 [0].Function = Fac_ERROR,
4423 [0].u.ERROR.invokeId = 8,
4424 [0].u.ERROR.errorValue = FacError_CCBS_AlreadyAccepted,
4426 [1].Function = Fac_RESULT,
4427 [1].u.RESULT.InvokeID = 9,
4429 [2].Function = Fac_REJECT,
4430 [2].u.REJECT.Code = FacReject_Gen_BadlyStructuredComponent,
4432 [3].Function = Fac_REJECT,
4433 [3].u.REJECT.InvokeIDPresent = 1,
4434 [3].u.REJECT.InvokeID = 10,
4435 [3].u.REJECT.Code = FacReject_Inv_InitiatorReleasing,
4437 [4].Function = Fac_REJECT,
4438 [4].u.REJECT.InvokeIDPresent = 1,
4439 [4].u.REJECT.InvokeID = 11,
4440 [4].u.REJECT.Code = FacReject_Res_MistypedResult,
4442 [5].Function = Fac_REJECT,
4443 [5].u.REJECT.InvokeIDPresent = 1,
4444 [5].u.REJECT.InvokeID = 12,
4445 [5].u.REJECT.Code = FacReject_Err_ErrorResponseUnexpected,
4447 [6].Function = Fac_StatusRequest,
4448 [6].u.StatusRequest.InvokeID = 13,
4449 [6].u.StatusRequest.ComponentType = FacComponent_Invoke,
4450 [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
4451 [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Contents =
"AB",
4452 [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Length = 3,
4453 [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Contents =
"CDE",
4454 [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Length = 4,
4455 [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Contents =
"FGHI",
4456 [6].u.StatusRequest.Component.Invoke.CompatibilityMode = 1,
4458 [7].Function = Fac_StatusRequest,
4459 [7].u.StatusRequest.InvokeID = 14,
4460 [7].u.StatusRequest.ComponentType = FacComponent_Result,
4461 [7].u.StatusRequest.Component.Result.Status = 2,
4463 [8].Function = Fac_CallInfoRetain,
4464 [8].u.CallInfoRetain.InvokeID = 15,
4465 [8].u.CallInfoRetain.CallLinkageID = 115,
4467 [9].Function = Fac_EraseCallLinkageID,
4468 [9].u.EraseCallLinkageID.InvokeID = 16,
4469 [9].u.EraseCallLinkageID.CallLinkageID = 105,
4471 [10].Function = Fac_CCBSDeactivate,
4472 [10].u.CCBSDeactivate.InvokeID = 17,
4473 [10].u.CCBSDeactivate.ComponentType = FacComponent_Invoke,
4474 [10].u.CCBSDeactivate.Component.Invoke.CCBSReference = 2,
4476 [11].Function = Fac_CCBSDeactivate,
4477 [11].u.CCBSDeactivate.InvokeID = 18,
4478 [11].u.CCBSDeactivate.ComponentType = FacComponent_Result,
4480 [12].Function = Fac_CCBSErase,
4481 [12].u.CCBSErase.InvokeID = 19,
4482 [12].u.CCBSErase.Q931ie.Bc.Length = 2,
4483 [12].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4484 [12].u.CCBSErase.AddressOfB.Party.Type = 0,
4485 [12].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 5,
4486 [12].u.CCBSErase.AddressOfB.Party.Number =
"33403",
4487 [12].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
4488 [12].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4489 [12].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information =
"3748",
4490 [12].u.CCBSErase.RecallMode = 1,
4491 [12].u.CCBSErase.CCBSReference = 102,
4492 [12].u.CCBSErase.Reason = 3,
4494 [13].Function = Fac_CCBSErase,
4495 [13].u.CCBSErase.InvokeID = 20,
4496 [13].u.CCBSErase.Q931ie.Bc.Length = 2,
4497 [13].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4498 [13].u.CCBSErase.AddressOfB.Party.Type = 1,
4499 [13].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
4500 [13].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 1,
4501 [13].u.CCBSErase.AddressOfB.Party.Number =
"18003020102",
4502 [13].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
4503 [13].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4504 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCountPresent = 1,
4505 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCount = 1,
4506 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information =
"3748",
4507 [13].u.CCBSErase.RecallMode = 1,
4508 [13].u.CCBSErase.CCBSReference = 102,
4509 [13].u.CCBSErase.Reason = 3,
4511 [14].Function = Fac_CCBSErase,
4512 [14].u.CCBSErase.InvokeID = 21,
4513 [14].u.CCBSErase.Q931ie.Bc.Length = 2,
4514 [14].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4515 [14].u.CCBSErase.AddressOfB.Party.Type = 2,
4516 [14].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4517 [14].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4518 [14].u.CCBSErase.AddressOfB.Subaddress.Type = 1,
4519 [14].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4520 [14].u.CCBSErase.AddressOfB.Subaddress.u.Nsap =
"6492",
4521 [14].u.CCBSErase.RecallMode = 1,
4522 [14].u.CCBSErase.CCBSReference = 102,
4523 [14].u.CCBSErase.Reason = 3,
4525 [15].Function = Fac_CCBSErase,
4526 [15].u.CCBSErase.InvokeID = 22,
4527 [15].u.CCBSErase.Q931ie.Bc.Length = 2,
4528 [15].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4529 [15].u.CCBSErase.AddressOfB.Party.Type = 3,
4530 [15].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4531 [15].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4532 [15].u.CCBSErase.RecallMode = 1,
4533 [15].u.CCBSErase.CCBSReference = 102,
4534 [15].u.CCBSErase.Reason = 3,
4536 [16].Function = Fac_CCBSErase,
4537 [16].u.CCBSErase.InvokeID = 23,
4538 [16].u.CCBSErase.Q931ie.Bc.Length = 2,
4539 [16].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4540 [16].u.CCBSErase.AddressOfB.Party.Type = 4,
4541 [16].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4542 [16].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4543 [16].u.CCBSErase.RecallMode = 1,
4544 [16].u.CCBSErase.CCBSReference = 102,
4545 [16].u.CCBSErase.Reason = 3,
4547 [17].Function = Fac_CCBSErase,
4548 [17].u.CCBSErase.InvokeID = 24,
4549 [17].u.CCBSErase.Q931ie.Bc.Length = 2,
4550 [17].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4551 [17].u.CCBSErase.AddressOfB.Party.Type = 5,
4552 [17].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
4553 [17].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 4,
4554 [17].u.CCBSErase.AddressOfB.Party.Number =
"18003020102",
4555 [17].u.CCBSErase.RecallMode = 1,
4556 [17].u.CCBSErase.CCBSReference = 102,
4557 [17].u.CCBSErase.Reason = 3,
4559 [18].Function = Fac_CCBSErase,
4560 [18].u.CCBSErase.InvokeID = 25,
4561 [18].u.CCBSErase.Q931ie.Bc.Length = 2,
4562 [18].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4563 [18].u.CCBSErase.AddressOfB.Party.Type = 8,
4564 [18].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4565 [18].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4566 [18].u.CCBSErase.RecallMode = 1,
4567 [18].u.CCBSErase.CCBSReference = 102,
4568 [18].u.CCBSErase.Reason = 3,
4570 [19].Function = Fac_CCBSRemoteUserFree,
4571 [19].u.CCBSRemoteUserFree.InvokeID = 26,
4572 [19].u.CCBSRemoteUserFree.Q931ie.Bc.Length = 2,
4573 [19].u.CCBSRemoteUserFree.Q931ie.Bc.Contents =
"JK",
4574 [19].u.CCBSRemoteUserFree.AddressOfB.Party.Type = 8,
4575 [19].u.CCBSRemoteUserFree.AddressOfB.Party.LengthOfNumber = 4,
4576 [19].u.CCBSRemoteUserFree.AddressOfB.Party.Number =
"1803",
4577 [19].u.CCBSRemoteUserFree.RecallMode = 1,
4578 [19].u.CCBSRemoteUserFree.CCBSReference = 102,
4580 [20].Function = Fac_CCBSCall,
4581 [20].u.CCBSCall.InvokeID = 27,
4582 [20].u.CCBSCall.CCBSReference = 115,
4584 [21].Function = Fac_CCBSStatusRequest,
4585 [21].u.CCBSStatusRequest.InvokeID = 28,
4586 [21].u.CCBSStatusRequest.ComponentType = FacComponent_Invoke,
4587 [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
4588 [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Contents =
"JK",
4589 [21].u.CCBSStatusRequest.Component.Invoke.RecallMode = 1,
4590 [21].u.CCBSStatusRequest.Component.Invoke.CCBSReference = 102,
4592 [22].Function = Fac_CCBSStatusRequest,
4593 [22].u.CCBSStatusRequest.InvokeID = 29,
4594 [22].u.CCBSStatusRequest.ComponentType = FacComponent_Result,
4595 [22].u.CCBSStatusRequest.Component.Result.Free = 1,
4597 [23].Function = Fac_CCBSBFree,
4598 [23].u.CCBSBFree.InvokeID = 30,
4599 [23].u.CCBSBFree.Q931ie.Bc.Length = 2,
4600 [23].u.CCBSBFree.Q931ie.Bc.Contents =
"JK",
4601 [23].u.CCBSBFree.AddressOfB.Party.Type = 8,
4602 [23].u.CCBSBFree.AddressOfB.Party.LengthOfNumber = 4,
4603 [23].u.CCBSBFree.AddressOfB.Party.Number =
"1803",
4604 [23].u.CCBSBFree.RecallMode = 1,
4605 [23].u.CCBSBFree.CCBSReference = 14,
4607 [24].Function = Fac_CCBSStopAlerting,
4608 [24].u.CCBSStopAlerting.InvokeID = 31,
4609 [24].u.CCBSStopAlerting.CCBSReference = 37,
4611 [25].Function = Fac_CCBSRequest,
4612 [25].u.CCBSRequest.InvokeID = 32,
4613 [25].u.CCBSRequest.ComponentType = FacComponent_Invoke,
4614 [25].u.CCBSRequest.Component.Invoke.CallLinkageID = 57,
4616 [26].Function = Fac_CCBSRequest,
4617 [26].u.CCBSRequest.InvokeID = 33,
4618 [26].u.CCBSRequest.ComponentType = FacComponent_Result,
4619 [26].u.CCBSRequest.Component.Result.RecallMode = 1,
4620 [26].u.CCBSRequest.Component.Result.CCBSReference = 102,
4622 [27].Function = Fac_CCBSInterrogate,
4623 [27].u.CCBSInterrogate.InvokeID = 34,
4624 [27].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4625 [27].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
4626 [27].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
4627 [27].u.CCBSInterrogate.Component.Invoke.AParty.Number =
"1803",
4628 [27].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
4629 [27].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
4631 [28].Function = Fac_CCBSInterrogate,
4632 [28].u.CCBSInterrogate.InvokeID = 35,
4633 [28].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4634 [28].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
4635 [28].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
4636 [28].u.CCBSInterrogate.Component.Invoke.AParty.Number =
"1803",
4638 [29].Function = Fac_CCBSInterrogate,
4639 [29].u.CCBSInterrogate.InvokeID = 36,
4640 [29].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4641 [29].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
4642 [29].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
4644 [30].Function = Fac_CCBSInterrogate,
4645 [30].u.CCBSInterrogate.InvokeID = 37,
4646 [30].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4648 [31].Function = Fac_CCBSInterrogate,
4649 [31].u.CCBSInterrogate.InvokeID = 38,
4650 [31].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4651 [31].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4653 [32].Function = Fac_CCBSInterrogate,
4654 [32].u.CCBSInterrogate.InvokeID = 39,
4655 [32].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4656 [32].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4657 [32].u.CCBSInterrogate.Component.Result.NumRecords = 1,
4658 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
4659 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
4660 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents =
"JK",
4661 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
4662 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
4663 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number =
"1803",
4664 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Type = 1,
4665 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Length = 4,
4666 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.u.Nsap =
"6492",
4668 [33].Function = Fac_CCBSInterrogate,
4669 [33].u.CCBSInterrogate.InvokeID = 40,
4670 [33].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4671 [33].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4672 [33].u.CCBSInterrogate.Component.Result.NumRecords = 2,
4673 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
4674 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
4675 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents =
"JK",
4676 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
4677 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
4678 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number =
"1803",
4679 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].CCBSReference = 102,
4680 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Length = 2,
4681 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Contents =
"LM",
4682 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Type = 8,
4683 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.LengthOfNumber = 4,
4684 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Number =
"6229",
4685 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Type = 1,
4686 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Length = 4,
4687 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.u.Nsap =
"8592",
4688 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Type = 1,
4689 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Length = 4,
4690 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.u.Nsap =
"6492",
4692 [34].Function = Fac_CCNRRequest,
4693 [34].u.CCNRRequest.InvokeID = 512,
4694 [34].u.CCNRRequest.ComponentType = FacComponent_Invoke,
4695 [34].u.CCNRRequest.Component.Invoke.CallLinkageID = 57,
4697 [35].Function = Fac_CCNRRequest,
4698 [35].u.CCNRRequest.InvokeID = 150,
4699 [35].u.CCNRRequest.ComponentType = FacComponent_Result,
4700 [35].u.CCNRRequest.Component.Result.RecallMode = 1,
4701 [35].u.CCNRRequest.Component.Result.CCBSReference = 102,
4703 [36].Function = Fac_CCNRInterrogate,
4704 [36].u.CCNRInterrogate.InvokeID = -129,
4705 [36].u.CCNRInterrogate.ComponentType = FacComponent_Invoke,
4707 [37].Function = Fac_CCNRInterrogate,
4708 [37].u.CCNRInterrogate.InvokeID = -3,
4709 [37].u.CCNRInterrogate.ComponentType = FacComponent_Result,
4710 [37].u.CCNRInterrogate.Component.Result.RecallMode = 1,
4712 [38].Function = Fac_CCBS_T_Call,
4713 [38].u.EctExecute.InvokeID = 41,
4715 [39].Function = Fac_CCBS_T_Suspend,
4716 [39].u.EctExecute.InvokeID = 42,
4718 [40].Function = Fac_CCBS_T_Resume,
4719 [40].u.EctExecute.InvokeID = 43,
4721 [41].Function = Fac_CCBS_T_RemoteUserFree,
4722 [41].u.EctExecute.InvokeID = 44,
4724 [42].Function = Fac_CCBS_T_Available,
4725 [42].u.EctExecute.InvokeID = 45,
4727 [43].Function = Fac_CCBS_T_Request,
4728 [43].u.CCBS_T_Request.InvokeID = 46,
4729 [43].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4730 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4731 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4732 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4733 [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4734 [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4735 [43].u.CCBS_T_Request.Component.Invoke.RetentionSupported = 1,
4736 [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4737 [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4738 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4739 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4740 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4742 [44].Function = Fac_CCBS_T_Request,
4743 [44].u.CCBS_T_Request.InvokeID = 47,
4744 [44].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4745 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4746 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4747 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4748 [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4749 [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4750 [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4751 [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4752 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4753 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4754 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4756 [45].Function = Fac_CCBS_T_Request,
4757 [45].u.CCBS_T_Request.InvokeID = 48,
4758 [45].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4759 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4760 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4761 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4762 [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4763 [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4764 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4765 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4766 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4768 [46].Function = Fac_CCBS_T_Request,
4769 [46].u.CCBS_T_Request.InvokeID = 49,
4770 [46].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4771 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4772 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4773 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4774 [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4775 [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4776 [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4777 [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4779 [47].Function = Fac_CCBS_T_Request,
4780 [47].u.CCBS_T_Request.InvokeID = 50,
4781 [47].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4782 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4783 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4784 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4785 [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4786 [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4788 [48].Function = Fac_CCBS_T_Request,
4789 [48].u.CCBS_T_Request.InvokeID = 51,
4790 [48].u.CCBS_T_Request.ComponentType = FacComponent_Result,
4791 [48].u.CCBS_T_Request.Component.Result.RetentionSupported = 1,
4793 [49].Function = Fac_CCNR_T_Request,
4794 [49].u.CCNR_T_Request.InvokeID = 52,
4795 [49].u.CCNR_T_Request.ComponentType = FacComponent_Invoke,
4796 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Type = 8,
4797 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4798 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4799 [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4800 [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4802 [50].Function = Fac_CCNR_T_Request,
4803 [50].u.CCNR_T_Request.InvokeID = 53,
4804 [50].u.CCNR_T_Request.ComponentType = FacComponent_Result,
4805 [50].u.CCNR_T_Request.Component.Result.RetentionSupported = 1,
4807 [51].Function = Fac_EctExecute,
4808 [51].u.EctExecute.InvokeID = 54,
4810 [52].Function = Fac_ExplicitEctExecute,
4811 [52].u.ExplicitEctExecute.InvokeID = 55,
4812 [52].u.ExplicitEctExecute.LinkID = 23,
4814 [53].Function = Fac_RequestSubaddress,
4815 [53].u.RequestSubaddress.InvokeID = 56,
4817 [54].Function = Fac_SubaddressTransfer,
4818 [54].u.SubaddressTransfer.InvokeID = 57,
4819 [54].u.SubaddressTransfer.Subaddress.Type = 1,
4820 [54].u.SubaddressTransfer.Subaddress.Length = 4,
4821 [54].u.SubaddressTransfer.Subaddress.u.Nsap =
"6492",
4823 [55].Function = Fac_EctLinkIdRequest,
4824 [55].u.EctLinkIdRequest.InvokeID = 58,
4825 [55].u.EctLinkIdRequest.ComponentType = FacComponent_Invoke,
4827 [56].Function = Fac_EctLinkIdRequest,
4828 [56].u.EctLinkIdRequest.InvokeID = 59,
4829 [56].u.EctLinkIdRequest.ComponentType = FacComponent_Result,
4830 [56].u.EctLinkIdRequest.Component.Result.LinkID = 76,
4832 [57].Function = Fac_EctInform,
4833 [57].u.EctInform.InvokeID = 60,
4834 [57].u.EctInform.Status = 1,
4835 [57].u.EctInform.RedirectionPresent = 1,
4836 [57].u.EctInform.Redirection.Type = 0,
4837 [57].u.EctInform.Redirection.Unscreened.Type = 8,
4838 [57].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
4839 [57].u.EctInform.Redirection.Unscreened.Number =
"6229",
4841 [58].Function = Fac_EctInform,
4842 [58].u.EctInform.InvokeID = 61,
4843 [58].u.EctInform.Status = 1,
4844 [58].u.EctInform.RedirectionPresent = 1,
4845 [58].u.EctInform.Redirection.Type = 1,
4847 [59].Function = Fac_EctInform,
4848 [59].u.EctInform.InvokeID = 62,
4849 [59].u.EctInform.Status = 1,
4850 [59].u.EctInform.RedirectionPresent = 1,
4851 [59].u.EctInform.Redirection.Type = 2,
4853 [60].Function = Fac_EctInform,
4854 [60].u.EctInform.InvokeID = 63,
4855 [60].u.EctInform.Status = 1,
4856 [60].u.EctInform.RedirectionPresent = 1,
4857 [60].u.EctInform.Redirection.Type = 3,
4858 [60].u.EctInform.Redirection.Unscreened.Type = 8,
4859 [60].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
4860 [60].u.EctInform.Redirection.Unscreened.Number =
"3340",
4862 [61].Function = Fac_EctInform,
4863 [61].u.EctInform.InvokeID = 64,
4864 [61].u.EctInform.Status = 1,
4865 [61].u.EctInform.RedirectionPresent = 0,
4867 [62].Function = Fac_EctLoopTest,
4868 [62].u.EctLoopTest.InvokeID = 65,
4869 [62].u.EctLoopTest.ComponentType = FacComponent_Invoke,
4870 [62].u.EctLoopTest.Component.Invoke.CallTransferID = 7,
4872 [63].Function = Fac_EctLoopTest,
4873 [63].u.EctLoopTest.InvokeID = 66,
4874 [63].u.EctLoopTest.ComponentType = FacComponent_Result,
4875 [63].u.EctLoopTest.Component.Result.LoopResult = 2,
4877 [64].Function = Fac_ActivationDiversion,
4878 [64].u.ActivationDiversion.InvokeID = 67,
4879 [64].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
4880 [64].u.ActivationDiversion.Component.Invoke.Procedure = 2,
4881 [64].u.ActivationDiversion.Component.Invoke.BasicService = 3,
4882 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
4883 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
4884 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number =
"1803",
4885 [64].u.ActivationDiversion.Component.Invoke.ServedUser.Type = 4,
4886 [64].u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 4,
4887 [64].u.ActivationDiversion.Component.Invoke.ServedUser.Number =
"5398",
4889 [65].Function = Fac_ActivationDiversion,
4890 [65].u.ActivationDiversion.InvokeID = 68,
4891 [65].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
4892 [65].u.ActivationDiversion.Component.Invoke.Procedure = 1,
4893 [65].u.ActivationDiversion.Component.Invoke.BasicService = 5,
4894 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
4895 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
4896 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number =
"1803",
4898 [66].Function = Fac_ActivationDiversion,
4899 [66].u.ActivationDiversion.InvokeID = 69,
4900 [66].u.ActivationDiversion.ComponentType = FacComponent_Result,
4902 [67].Function = Fac_DeactivationDiversion,
4903 [67].u.DeactivationDiversion.InvokeID = 70,
4904 [67].u.DeactivationDiversion.ComponentType = FacComponent_Invoke,
4905 [67].u.DeactivationDiversion.Component.Invoke.Procedure = 1,
4906 [67].u.DeactivationDiversion.Component.Invoke.BasicService = 5,
4908 [68].Function = Fac_DeactivationDiversion,
4909 [68].u.DeactivationDiversion.InvokeID = 71,
4910 [68].u.DeactivationDiversion.ComponentType = FacComponent_Result,
4912 [69].Function = Fac_ActivationStatusNotificationDiv,
4913 [69].u.ActivationStatusNotificationDiv.InvokeID = 72,
4914 [69].u.ActivationStatusNotificationDiv.Procedure = 1,
4915 [69].u.ActivationStatusNotificationDiv.BasicService = 5,
4916 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Type = 4,
4917 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.LengthOfNumber = 4,
4918 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Number =
"1803",
4920 [70].Function = Fac_DeactivationStatusNotificationDiv,
4921 [70].u.DeactivationStatusNotificationDiv.InvokeID = 73,
4922 [70].u.DeactivationStatusNotificationDiv.Procedure = 1,
4923 [70].u.DeactivationStatusNotificationDiv.BasicService = 5,
4925 [71].Function = Fac_InterrogationDiversion,
4926 [71].u.InterrogationDiversion.InvokeID = 74,
4927 [71].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
4928 [71].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
4929 [71].u.InterrogationDiversion.Component.Invoke.BasicService = 5,
4931 [72].Function = Fac_InterrogationDiversion,
4932 [72].u.InterrogationDiversion.InvokeID = 75,
4933 [72].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
4934 [72].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
4936 [73].Function = Fac_InterrogationDiversion,
4937 [73].u.InterrogationDiversion.InvokeID = 76,
4938 [73].u.InterrogationDiversion.ComponentType = FacComponent_Result,
4939 [73].u.InterrogationDiversion.Component.Result.NumRecords = 2,
4940 [73].u.InterrogationDiversion.Component.Result.List[0].Procedure = 2,
4941 [73].u.InterrogationDiversion.Component.Result.List[0].BasicService = 5,
4942 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Type = 4,
4943 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.LengthOfNumber = 4,
4944 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Number =
"1803",
4945 [73].u.InterrogationDiversion.Component.Result.List[1].Procedure = 1,
4946 [73].u.InterrogationDiversion.Component.Result.List[1].BasicService = 3,
4947 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Type = 4,
4948 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.LengthOfNumber = 4,
4949 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Number =
"1903",
4950 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Type = 4,
4951 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.LengthOfNumber = 4,
4952 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Number =
"5398",
4954 [74].Function = Fac_DiversionInformation,
4955 [74].u.DiversionInformation.InvokeID = 77,
4956 [74].u.DiversionInformation.DiversionReason = 3,
4957 [74].u.DiversionInformation.BasicService = 5,
4958 [74].u.DiversionInformation.ServedUserSubaddress.Type = 1,
4959 [74].u.DiversionInformation.ServedUserSubaddress.Length = 4,
4960 [74].u.DiversionInformation.ServedUserSubaddress.u.Nsap =
"6492",
4961 [74].u.DiversionInformation.CallingAddressPresent = 1,
4962 [74].u.DiversionInformation.CallingAddress.Type = 0,
4963 [74].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 3,
4964 [74].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
4965 [74].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
4966 [74].u.DiversionInformation.CallingAddress.Address.Party.Number =
"1803",
4967 [74].u.DiversionInformation.OriginalCalledPresent = 1,
4968 [74].u.DiversionInformation.OriginalCalled.Type = 1,
4969 [74].u.DiversionInformation.LastDivertingPresent = 1,
4970 [74].u.DiversionInformation.LastDiverting.Type = 2,
4971 [74].u.DiversionInformation.LastDivertingReasonPresent = 1,
4972 [74].u.DiversionInformation.LastDivertingReason = 3,
4973 [74].u.DiversionInformation.UserInfo.Length = 5,
4974 [74].u.DiversionInformation.UserInfo.Contents =
"79828",
4976 [75].Function = Fac_DiversionInformation,
4977 [75].u.DiversionInformation.InvokeID = 78,
4978 [75].u.DiversionInformation.DiversionReason = 3,
4979 [75].u.DiversionInformation.BasicService = 5,
4980 [75].u.DiversionInformation.CallingAddressPresent = 1,
4981 [75].u.DiversionInformation.CallingAddress.Type = 1,
4982 [75].u.DiversionInformation.OriginalCalledPresent = 1,
4983 [75].u.DiversionInformation.OriginalCalled.Type = 2,
4984 [75].u.DiversionInformation.LastDivertingPresent = 1,
4985 [75].u.DiversionInformation.LastDiverting.Type = 1,
4987 [76].Function = Fac_DiversionInformation,
4988 [76].u.DiversionInformation.InvokeID = 79,
4989 [76].u.DiversionInformation.DiversionReason = 2,
4990 [76].u.DiversionInformation.BasicService = 3,
4991 [76].u.DiversionInformation.CallingAddressPresent = 1,
4992 [76].u.DiversionInformation.CallingAddress.Type = 2,
4994 [77].Function = Fac_DiversionInformation,
4995 [77].u.DiversionInformation.InvokeID = 80,
4996 [77].u.DiversionInformation.DiversionReason = 3,
4997 [77].u.DiversionInformation.BasicService = 5,
4998 [77].u.DiversionInformation.CallingAddressPresent = 1,
4999 [77].u.DiversionInformation.CallingAddress.Type = 3,
5000 [77].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 2,
5001 [77].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
5002 [77].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
5003 [77].u.DiversionInformation.CallingAddress.Address.Party.Number =
"1803",
5005 [78].Function = Fac_DiversionInformation,
5006 [78].u.DiversionInformation.InvokeID = 81,
5007 [78].u.DiversionInformation.DiversionReason = 2,
5008 [78].u.DiversionInformation.BasicService = 4,
5009 [78].u.DiversionInformation.UserInfo.Length = 5,
5010 [78].u.DiversionInformation.UserInfo.Contents =
"79828",
5012 [79].Function = Fac_DiversionInformation,
5013 [79].u.DiversionInformation.InvokeID = 82,
5014 [79].u.DiversionInformation.DiversionReason = 2,
5015 [79].u.DiversionInformation.BasicService = 4,
5017 [80].Function = Fac_CallDeflection,
5018 [80].u.CallDeflection.InvokeID = 83,
5019 [80].u.CallDeflection.ComponentType = FacComponent_Invoke,
5020 [80].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5021 [80].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5022 [80].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5023 [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
5024 [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 1,
5026 [81].Function = Fac_CallDeflection,
5027 [81].u.CallDeflection.InvokeID = 84,
5028 [81].u.CallDeflection.ComponentType = FacComponent_Invoke,
5029 [81].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5030 [81].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5031 [81].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5032 [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
5033 [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0,
5035 [82].Function = Fac_CallDeflection,
5036 [82].u.CallDeflection.InvokeID = 85,
5037 [82].u.CallDeflection.ComponentType = FacComponent_Invoke,
5038 [82].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5039 [82].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5040 [82].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5042 [83].Function = Fac_CallDeflection,
5043 [83].u.CallDeflection.InvokeID = 86,
5044 [83].u.CallDeflection.ComponentType = FacComponent_Result,
5046 [84].Function = Fac_CallRerouteing,
5047 [84].u.CallRerouteing.InvokeID = 87,
5048 [84].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5049 [84].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5050 [84].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5051 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5052 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5053 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5054 [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5055 [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5056 [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 3,
5057 [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Contents =
"RTG",
5058 [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 2,
5059 [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Contents =
"MY",
5060 [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 5,
5061 [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Contents =
"YEHAW",
5062 [84].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
5063 [84].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
5064 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Type = 1,
5065 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 4,
5066 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.u.Nsap =
"6492",
5068 [85].Function = Fac_CallRerouteing,
5069 [85].u.CallRerouteing.InvokeID = 88,
5070 [85].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5071 [85].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5072 [85].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5073 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5074 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5075 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5076 [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5077 [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5078 [85].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
5079 [85].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
5081 [86].Function = Fac_CallRerouteing,
5082 [86].u.CallRerouteing.InvokeID = 89,
5083 [86].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5084 [86].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5085 [86].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5086 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5087 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5088 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5089 [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5090 [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5091 [86].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 2,
5093 [87].Function = Fac_CallRerouteing,
5094 [87].u.CallRerouteing.InvokeID = 90,
5095 [87].u.CallRerouteing.ComponentType = FacComponent_Result,
5097 [88].Function = Fac_InterrogateServedUserNumbers,
5098 [88].u.InterrogateServedUserNumbers.InvokeID = 91,
5099 [88].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Invoke,
5101 [89].Function = Fac_InterrogateServedUserNumbers,
5102 [89].u.InterrogateServedUserNumbers.InvokeID = 92,
5103 [89].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Result,
5104 [89].u.InterrogateServedUserNumbers.Component.Result.NumRecords = 2,
5105 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Type = 4,
5106 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].LengthOfNumber = 4,
5107 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Number =
"1803",
5108 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Type = 4,
5109 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].LengthOfNumber = 4,
5110 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Number =
"5786",
5112 [90].Function = Fac_DivertingLegInformation1,
5113 [90].u.DivertingLegInformation1.InvokeID = 93,
5114 [90].u.DivertingLegInformation1.DiversionReason = 4,
5115 [90].u.DivertingLegInformation1.SubscriptionOption = 1,
5116 [90].u.DivertingLegInformation1.DivertedToPresent = 1,
5117 [90].u.DivertingLegInformation1.DivertedTo.Type = 2,
5119 [91].Function = Fac_DivertingLegInformation1,
5120 [91].u.DivertingLegInformation1.InvokeID = 94,
5121 [91].u.DivertingLegInformation1.DiversionReason = 4,
5122 [91].u.DivertingLegInformation1.SubscriptionOption = 1,
5124 [92].Function = Fac_DivertingLegInformation2,
5125 [92].u.DivertingLegInformation2.InvokeID = 95,
5126 [92].u.DivertingLegInformation2.DiversionCounter = 3,
5127 [92].u.DivertingLegInformation2.DiversionReason = 2,
5128 [92].u.DivertingLegInformation2.DivertingPresent = 1,
5129 [92].u.DivertingLegInformation2.Diverting.Type = 2,
5130 [92].u.DivertingLegInformation2.OriginalCalledPresent = 1,
5131 [92].u.DivertingLegInformation2.OriginalCalled.Type = 1,
5133 [93].Function = Fac_DivertingLegInformation2,
5134 [93].u.DivertingLegInformation2.InvokeID = 96,
5135 [93].u.DivertingLegInformation2.DiversionCounter = 3,
5136 [93].u.DivertingLegInformation2.DiversionReason = 2,
5137 [93].u.DivertingLegInformation2.OriginalCalledPresent = 1,
5138 [93].u.DivertingLegInformation2.OriginalCalled.Type = 1,
5140 [94].Function = Fac_DivertingLegInformation2,
5141 [94].u.DivertingLegInformation2.InvokeID = 97,
5142 [94].u.DivertingLegInformation2.DiversionCounter = 1,
5143 [94].u.DivertingLegInformation2.DiversionReason = 2,
5145 [95].Function = Fac_DivertingLegInformation3,
5146 [95].u.DivertingLegInformation3.InvokeID = 98,
5147 [95].u.DivertingLegInformation3.PresentationAllowedIndicator = 1,
5154 const char *channame;
5158 const char *served_nr;
5164 e->
command =
"misdn send facility";
5165 e->
usage =
"Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
5166 "\t type is one of:\n"
5167 "\t - calldeflect\n"
5168 #if defined(AST_MISDN_ENHANCEMENTS)
5169 "\t - callrerouting\n"
5172 "\t - CFDeactivate\n";
5183 if (strstr(a->
argv[3],
"calldeflect")) {
5185 ast_verbose(
"calldeflect requires 1 arg: ToNumber\n\n");
5188 channame = a->
argv[4];
5191 ast_verbose(
"Sending Calldeflection (%s) to %s\n", nr, channame);
5194 ast_verbose(
"Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5199 #if defined(AST_MISDN_ENHANCEMENTS)
5200 max_len =
sizeof(tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
5201 if (max_len < strlen(nr)) {
5202 ast_verbose(
"Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5203 nr, channame, max_len);
5208 tmp->
bc->
fac_out.Function = Fac_CallDeflection;
5209 tmp->
bc->
fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
5210 tmp->
bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
5211 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
5212 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
5213 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;
5214 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr);
5215 strcpy((
char *) tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr);
5216 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
5220 max_len =
sizeof(tmp->
bc->
fac_out.u.CDeflection.DeflectedToNumber) - 1;
5221 if (max_len < strlen(nr)) {
5222 ast_verbose(
"Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5223 nr, channame, max_len);
5229 tmp->
bc->
fac_out.u.CDeflection.PresentationAllowed = 0;
5231 strcpy((
char *) tmp->
bc->
fac_out.u.CDeflection.DeflectedToNumber, nr);
5239 #if defined(AST_MISDN_ENHANCEMENTS)
5240 }
else if (strstr(a->
argv[3],
"callrerouteing") || strstr(a->
argv[3],
"callrerouting")) {
5242 ast_verbose(
"callrerouting requires 1 arg: ToNumber\n\n");
5245 channame = a->
argv[4];
5248 ast_verbose(
"Sending Callrerouting (%s) to %s\n", nr, channame);
5251 ast_verbose(
"Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5256 max_len =
sizeof(tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
5257 if (max_len < strlen(nr)) {
5258 ast_verbose(
"Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5259 nr, channame, max_len);
5264 tmp->
bc->
fac_out.Function = Fac_CallRerouteing;
5265 tmp->
bc->
fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
5266 tmp->
bc->
fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
5268 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;
5269 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
5271 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;
5272 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr);
5273 strcpy((
char *) tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr);
5274 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
5276 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
5279 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
5280 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
5281 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
5282 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
5283 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
5284 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
5285 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
5287 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;
5288 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;
5296 }
else if (strstr(a->
argv[3],
"CFActivate")) {
5298 ast_verbose(
"CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
5301 port = atoi(a->
argv[4]);
5302 served_nr = a->
argv[5];
5307 ast_verbose(
"Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
5309 #if defined(AST_MISDN_ENHANCEMENTS)
5310 bc->
fac_out.Function = Fac_ActivationDiversion;
5311 bc->
fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id;
5312 bc->
fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke;
5313 bc->
fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;
5314 bc->
fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;
5316 served_nr,
sizeof(bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number));
5317 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5318 strlen((
char *) bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number);
5319 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;
5321 nr,
sizeof(bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number));
5322 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber =
5323 strlen((
char *) bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number);
5324 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;
5325 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0;
5329 bc->
fac_out.Function = Fac_CFActivate;
5330 bc->
fac_out.u.CFActivate.BasicService = 0;
5331 bc->
fac_out.u.CFActivate.Procedure = 0;
5339 }
else if (strstr(a->
argv[3],
"CFDeactivate")) {
5341 ast_verbose(
"CFDeactivate requires 1 arg: FromNumber\n\n");
5344 port = atoi(a->
argv[4]);
5345 served_nr = a->
argv[5];
5348 ast_verbose(
"Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr);
5350 #if defined(AST_MISDN_ENHANCEMENTS)
5351 bc->
fac_out.Function = Fac_DeactivationDiversion;
5352 bc->
fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id;
5353 bc->
fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke;
5354 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;
5355 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;
5357 served_nr,
sizeof(bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number));
5358 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5359 strlen((
char *) bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number);
5360 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;
5364 bc->
fac_out.Function = Fac_CFDeactivate;
5365 bc->
fac_out.u.CFDeactivate.BasicService = 0;
5366 bc->
fac_out.u.CFDeactivate.Procedure = 0;
5373 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
5374 }
else if (strstr(a->
argv[3],
"test")) {
5378 ast_verbose(
"test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
5381 port = atoi(a->
argv[4]);
5383 channame = a->
argv[4];
5387 msg_number = atoi(a->
argv[5]);
5390 tmp->
bc->
fac_out = Fac_Msgs[msg_number];
5400 }
else if (a->
argc < 6) {
5401 for (msg_number = 0; msg_number <
ARRAY_LEN(Fac_Msgs); ++msg_number) {
5403 bc->
fac_out = Fac_Msgs[msg_number];
5411 msg_number = atoi(a->
argv[5]);
5414 bc->
fac_out = Fac_Msgs[msg_number];
5423 }
else if (strstr(a->
argv[3],
"register")) {
5428 port = atoi(a->
argv[4]);
5430 bc = misdn_lib_get_register_bc(port);
5432 ast_verbose(
"Could not allocate REGISTER bc struct\n\n");
5453 e->
command =
"misdn send restart";
5455 "Usage: misdn send restart [port [channel]]\n"
5456 " Send a restart for every bchannel on the given port.\n";
5466 port = atoi(a->
argv[3]);
5469 channel = atoi(a->
argv[4]);
5480 const char *channame;
5487 e->
command =
"misdn send digit";
5489 "Usage: misdn send digit <channel> \"<msg>\" \n"
5490 " Send <digit> to <channel> as DTMF Tone\n"
5491 " when channel is a mISDN channel\n";
5501 channame = a->
argv[3];
5503 msglen = strlen(msg);
5505 ast_cli(a->
fd,
"Sending %s to %s\n", msg, channame);
5509 ast_cli(a->
fd,
"Sending %s to %s failed Channel does not exist\n", msg, channame);
5513 for (i = 0; i < msglen; i++) {
5517 ast_cli(a->
fd,
"Sending: %c\n", msg[i]);
5535 const char *channame;
5540 e->
command =
"misdn toggle echocancel";
5542 "Usage: misdn toggle echocancel <channel>\n"
5543 " Toggle EchoCancel on mISDN Channel.\n";
5553 channame = a->
argv[3];
5555 ast_cli(a->
fd,
"Toggling EchoCancel on %s\n", channame);
5559 ast_cli(a->
fd,
"Toggling EchoCancel %s failed Channel does not exist\n", channame);
5567 update_pipeline_config(tmp->
bc);
5582 const char *channame;
5588 e->
command =
"misdn send display";
5590 "Usage: misdn send display <channel> \"<msg>\" \n"
5591 " Send <msg> to <channel> as Display Message\n"
5592 " when channel is a mISDN channel\n";
5602 channame = a->
argv[3];
5605 ast_cli(a->
fd,
"Sending %s to %s\n", msg, channame);
5608 if (tmp && tmp->
bc) {
5616 ast_cli(a->
fd,
"No such channel %s\n", channame);
5636 if (a->
word[0] ==
'p') {
5638 }
else if (a->
word[0] ==
'o') {
5643 if (a->
word[0] ==
'o') {
5655 int wordlen = strlen(a->
word);
5661 if ((!strncmp(a->
word,
"description", wordlen)) && (++which > a->
n)) {
5664 if ((!strncmp(a->
word,
"descriptions", wordlen)) && (++which > a->
n)) {
5667 if ((!strncmp(a->
word,
"0", wordlen)) && (++which > a->
n)) {
5671 snprintf(buffer,
sizeof(buffer),
"%d", port);
5672 if ((!strncmp(a->
word, buffer, wordlen)) && (++which > a->
n)) {
5678 if (strstr(a->
line,
"description ")) {
5684 if (!wordlen || !strncmp(a->
word, buffer, wordlen)) {
5685 if (++which > a->
n) {
5690 }
else if (strstr(a->
line,
"descriptions ")) {
5691 if ((!wordlen || !strncmp(a->
word,
"general", wordlen)) && (++which > a->
n)) {
5694 if ((!wordlen || !strncmp(a->
word,
"ports", wordlen)) && (++which > a->
n)) {
5746 if (! ast || ! bc) {
5769 chan_misdn_log(2, port,
" --> pres: %d screen: %d\n", pres, screen);
5771 if (pres < 0 || screen < 0) {
5798 if (len <= 100 || len > 8000) {
5799 chan_misdn_log(0, bc->
port,
"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
5803 if (threshold > len) {
5804 chan_misdn_log(0, bc->
port,
"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
5808 cb_log(0, bc->
port,
"config_jb: We've got a Jitterbuffer Already on this port.\n");
5845 chan_misdn_log(0, port,
" --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
5856 misdn_cfg_get(bc->
port, MISDN_CFG_PIPELINE, bc->pipeline,
sizeof(bc->pipeline));
5858 if (*bc->pipeline) {
5865 }
else if (ec > 1) {
5866 snprintf(bc->pipeline,
sizeof(bc->pipeline),
"mg2ec(deftaps=%d)", ec);
5875 int port = bc->
port;
5881 }
else if (ec > 1) {
5911 if (! ast || ! bc) {
5969 update_pipeline_config(bc);
5993 if (strstr(faxdetect,
"outgoing") || strstr(faxdetect,
"both")) {
5994 ch->
faxdetect = strstr(faxdetect,
"nojump") ? 2 : 1;
6024 if (strstr(faxdetect,
"incoming") || strstr(faxdetect,
"both")) {
6025 ch->
faxdetect = (strstr(faxdetect,
"nojump")) ? 2 : 1;
6083 memset(&update_connected, 0,
sizeof(update_connected));
6091 connected.
id.
tag = cid_tag;
6092 connected.
source = source;
6111 memset(&update_caller, 0,
sizeof(update_caller));
6127 caller.
id.
tag = cid_tag;
6128 caller.
ani.
tag = cid_tag;
6187 if (0 <= number_type) {
6215 if (0 <= number_type) {
6276 #if defined(AST_MISDN_ENHANCEMENTS)
6281 bc->
fac_out.Function = Fac_RequestSubaddress;
6282 bc->
fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
6289 #if defined(AST_MISDN_ENHANCEMENTS)
6292 bc->
fac_out.Function = Fac_EctInform;
6293 bc->
fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
6294 bc->
fac_out.u.EctInform.Status = 1;
6295 bc->
fac_out.u.EctInform.RedirectionPresent = 1;
6296 misdn_PresentedNumberUnscreened_fill(&bc->
fac_out.u.EctInform.Redirection,
6374 memset(&update_redirecting, 0,
sizeof(update_redirecting));
6396 redirecting.
to.
tag = tag;
6449 #if defined(AST_MISDN_ENHANCEMENTS)
6454 if (!bc->div_leg_3_tx_pending
6457 bc->
fac_out.Function = Fac_DivertingLegInformation1;
6458 bc->
fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
6459 bc->
fac_out.u.DivertingLegInformation1.DiversionReason =
6461 bc->
fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;
6462 bc->
fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
6463 misdn_PresentedNumberUnscreened_fill(&bc->
fac_out.u.DivertingLegInformation1.DivertedTo, &bc->
redirecting.
to);
6467 bc->div_leg_3_tx_pending = 0;
6470 bc->
fac_out.Function = Fac_DivertingLegInformation3;
6471 bc->
fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6472 bc->
fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6503 ast_log(
LOG_WARNING,
" --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
6508 ast_log(
LOG_WARNING,
" --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->
name);
6532 #if defined(AST_MISDN_ENHANCEMENTS)
6533 if ((ch->peer = misdn_cc_caller_get(ast))) {
6535 ch->peer->chan ?
"available" :
"NULL");
6538 if (ch->record_id != -1) {
6539 struct misdn_cc_record *cc_record;
6543 cc_record = misdn_cc_find_by_id(ch->record_id);
6553 newbc->
dialed = cc_record->redial.dialed;
6554 newbc->
caller = cc_record->redial.caller;
6556 newbc->
capability = cc_record->redial.capability;
6557 newbc->
hdlc = cc_record->redial.hdlc;
6560 if (cc_record->ptp) {
6561 newbc->
fac_out.Function = Fac_CCBS_T_Call;
6562 newbc->
fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
6564 newbc->
fac_out.Function = Fac_CCBSCall;
6565 newbc->
fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
6566 newbc->
fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
6619 if (number_type < 0) {
6665 #if defined(AST_MISDN_ENHANCEMENTS)
6672 newbc->
fac_out.Function = Fac_DivertingLegInformation2;
6673 newbc->
fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id;
6674 newbc->
fac_out.u.DivertingLegInformation2.DivertingPresent = 1;
6675 misdn_PresentedNumberUnscreened_fill(
6676 &newbc->
fac_out.u.DivertingLegInformation2.Diverting,
6681 newbc->
fac_out.u.DivertingLegInformation2.Diverting.Type = 1;
6684 newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter = 1;
6685 newbc->
fac_out.u.DivertingLegInformation2.DiversionReason = 0;
6688 newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter =
6690 newbc->
fac_out.u.DivertingLegInformation2.DiversionReason =
6694 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
6695 if (1 < newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter) {
6696 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
6697 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;
6704 newbc->div_leg_3_rx_wanted = 1;
6713 snprintf(tmp,
sizeof(tmp),
"%d", exceed);
6720 #if defined(AST_MISDN_ENHANCEMENTS)
6721 if (newbc->
fac_out.Function != Fac_None) {
6731 chan_misdn_log(0, port,
" --> * Theres no Channel at the moment .. !\n");
6732 chan_misdn_log(1, port,
" --> * SEND: State Down pid:%d\n", newbc ? newbc->
pid : -1);
6738 chan_misdn_log(2, port,
" --> * SEND: State Dialing pid:%d\n", newbc ? newbc->
pid : 1);
6770 chan_misdn_log(1, 0,
" --> Got Answer, but there is no bc obj ??\n");
6820 #if defined(AST_MISDN_ENHANCEMENTS)
6821 if (p->
bc->div_leg_3_tx_pending) {
6822 p->
bc->div_leg_3_tx_pending = 0;
6825 p->
bc->
fac_out.Function = Fac_DivertingLegInformation3;
6826 p->
bc->
fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6827 p->
bc->
fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6848 char buf[2] = { digit, 0 };
6915 chan_misdn_log(1, 0,
"* IND : Indication [%d] ignored on %s\n", cond,
6919 chan_misdn_log(1, 0,
"* IND : Indication [%d] ignored on hold %s\n",
6948 chan_misdn_log(2, p->
bc->
port,
" --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->
bc->
pid);
7077 "misdn_hangup: Could not find held bc for (%s)\n", ast->
name);
7087 ast_debug(1,
"State Reserved (or nothing) => chanIsAvail\n");
7125 tmpcause = atoi(var);
7138 "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
7157 ast_log(
LOG_NOTICE,
"release channel, in INCOMING_SETUP state.. no other events happened\n");
7272 *tmp->
bc->pipeline = 0;
7280 if (strcmp(ast->
exten,
"fax")) {
7287 ast_verb(3,
"Redirecting %s to fax extension (context:%s)\n", ast->
name, context);
7297 ast_debug(1,
"Already in a fax extension, not redirecting\n");
7301 ast_verb(3,
"Not redirecting %s to fax extension, nojump is set.\n", ast->
name);
7323 struct pollfd pfd = { .fd = -1, .events = POLLIN };
7339 pfd.fd = tmp->
pipe[0];
7350 }
else if (pfd.revents & POLLIN) {
7413 chan_misdn_log(7, 0,
"misdn_write: Returning because hold active\n");
7442 if (!strcmp(frame->
src,
"ast_prod")) {
7467 for (i = 0; i < max; i++) {
7480 "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
7499 cb_log(0, ch->
bc->
port,
"Misdn Jitterbuffer Overflow.\n");
7540 if (! p1_b || ! p2_b) {
7556 chan_misdn_log(1, ch1->
bc->
port,
"* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n",
7713 #if defined(AST_MISDN_ENHANCEMENTS)
7739 if (-1 < ch->
pipe[0]) {
7742 if (-1 < ch->
pipe[1]) {
7763 #if defined(AST_MISDN_ENHANCEMENTS)
7783 #if defined(AST_MISDN_ENHANCEMENTS)
7784 int cc_retry_call = 0;
7785 long record_id = -1;
7786 struct misdn_cc_record *cc_record;
7787 const char *err_msg;
7797 snprintf(dial_str,
sizeof(dial_str),
"%s/%s", misdn_type, (
char *) data);
7815 if (
args.intf[0] ==
'g' &&
args.intf[1] ==
':') {
7820 #if defined(AST_MISDN_ENHANCEMENTS)
7821 }
else if (strcmp(
args.intf,
"cc") == 0) {
7824 }
else if ((p = strchr(
args.intf,
':'))) {
7828 port = atoi(
args.intf);
7829 chan_misdn_log(2, port,
" --> Call on preselected Channel (%d).\n", channel);
7831 port = atoi(
args.intf);
7834 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
7838 #if defined(AST_MISDN_ENHANCEMENTS)
7839 if (cc_retry_call) {
7841 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str);
7844 if (!isdigit(*
args.ext)) {
7845 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
7848 record_id = atol(
args.ext);
7851 cc_record = misdn_cc_find_by_id(record_id);
7854 err_msg = misdn_cc_record_not_found;
7858 if (!cc_record->activated) {
7860 err_msg =
"Call completion has not been activated";
7864 port = cc_record->port;
7902 port_start = rr->
port;
7905 if (strcasecmp(cfg_group, group)) {
7919 }
else if (port_up < 0) {
7929 if (wraped && (rr->
port == port_start) && (rr->
channel == bchan_start)) {
7941 if (wraped && (rr->
port == port_start) && (rr->
channel <= bchan_start)) {
7943 }
else if (!newbc || (rr->
channel == maxbchans)) {
7950 }
while (!newbc && (rr->
port > 0));
7957 if (!strcasecmp(cfg_group, group)) {
7979 "Could not Dial out on group '%s'.\n"
7980 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
7981 "\tOr there was no free channel on none of the ports\n\n",
7988 chan_misdn_log(1, port,
" --> preselected_channel: %d\n", channel);
7992 ast_log(
LOG_WARNING,
"Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
8001 ast_log(
LOG_ERROR,
"Could not create call record for Dial(%s)\n", dial_str);
8010 ast_log(
LOG_ERROR,
"Could not create Asterisk channel for Dial(%s)\n", dial_str);
8014 #if defined(AST_MISDN_ENHANCEMENTS)
8015 cl->record_id = record_id;
8036 if (tmp && tmp->
bc) {
8049 .description =
"Channel driver for mISDN Support (Bri/Pri)",
8068 .description =
"Channel driver for mISDN Support (Bri/Pri)",
8089 int chan_offset = 0;
8094 if (tmp_port == port) {
8103 snprintf(newname,
sizeof(newname),
"%s/%d-", misdn_type, chan_offset + c);
8104 if (strncmp(tmp->
name, newname, strlen(newname))) {
8105 snprintf(newname,
sizeof(newname),
"%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
8116 int chan_offset = 0;
8121 if (tmp_port == port) {
8134 tmp =
ast_channel_alloc(1, state, cid_num, cid_name,
"", exten,
"", linkedid, 0,
"%s/%s%d-u%d", misdn_type, c ?
"" :
"tmp", chan_offset + c, glob_channel++);
8136 chan_misdn_log(2, port,
" --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
8170 if (pipe(chlist->
pipe) < 0) {
8191 for (help = cl_te; help; help = help->
next) {
8192 if (help->
bc == bc) {
8201 "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8218 chan_misdn_log(6, bc->
port,
"$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n",
8224 for (help = cl_te; help; help = help->
next) {
8234 "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8249 for (help = cl_te; help; help = help->
next) {
8261 #define TRANSFER_ON_HELD_CALL_HANGUP 1
8262 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
8283 for (list = cl_te; list; list = list->
next) {
8286 switch (list->
state) {
8318 for (help = cl_te; help->
next; help = help->
next) {
8337 if (cl_te == chan) {
8339 cl_te = cl_te->
next;
8346 for (help = cl_te; help->
next; help = help->
next) {
8347 if (help->
next == chan) {
8376 int port = bc->
port;
8379 cb_log(1, port,
"Cannot hangup chan, no ch\n");
8383 cb_log(5, port,
"hangup_chan called\n");
8386 cb_log(2, port,
" --> hangup\n");
8396 cb_log(2, port,
" --> No need to queue hangup\n");
8404 cb_log(2, port,
" --> queue_hangup\n");
8407 cb_log(1, port,
"Cannot hangup chan, no ast\n");
8452 "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
8470 --misdn_out_calls[bc->
port];
8472 --misdn_in_calls[bc->
port];
8554 switch (active_ch->
state) {
8580 target = active_ch->
ast;
8607 transferee, &transferee_colp, 1);
8641 "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
8649 strcpy(ast->
exten,
"s");
8703 switch (bc->
cause) {
8750 if (tmp && (atoi(tmp) == 1)) {
8780 snprintf(tmp,
sizeof(tmp),
"%d", bc->
pid);
8789 snprintf(tmp,
sizeof(tmp),
"%d", bc->
urate);
8807 misdn_in_calls[port]++;
8809 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
8811 return misdn_in_calls[port] - max_in_calls;
8823 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
8825 return (misdn_out_calls[port] + 1) - max_out_calls;
8828 misdn_out_calls[port]++;
8856 #if defined(AST_MISDN_ENHANCEMENTS)
8866 static void misdn_cc_handle_ccbs_status_request(
int port,
const struct FacParm *facility)
8868 struct misdn_cc_record *cc_record;
8871 switch (facility->u.CCBSStatusRequest.ComponentType) {
8872 case FacComponent_Invoke:
8875 dummy.fac_out.Function = Fac_CCBSStatusRequest;
8876 dummy.fac_out.u.CCBSStatusRequest.InvokeID = facility->u.CCBSStatusRequest.InvokeID;
8877 dummy.fac_out.u.CCBSStatusRequest.ComponentType = FacComponent_Result;
8881 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSStatusRequest.Component.Invoke.CCBSReference);
8883 dummy.fac_out.u.CCBSStatusRequest.Component.Result.Free = cc_record->party_a_free;
8886 dummy.fac_out.u.CCBSStatusRequest.Component.Result.Free = 1;
8896 chan_misdn_log(0, port,
" --> not yet handled: facility type:0x%04X\n", facility->Function);
8902 #if defined(AST_MISDN_ENHANCEMENTS)
8912 static void misdn_cc_pbx_notify(
long record_id,
const struct misdn_cc_notify *notify)
8917 static unsigned short sequence = 0;
8920 snprintf(id_str,
sizeof(id_str),
"%ld", record_id);
8922 notify->exten, notify->context, NULL, 0,
8923 "mISDN-CC/%ld-%X", record_id, (
unsigned) ++sequence);
8936 ast_verb(1,
"Started pbx for call completion notify channel %s\n", chan->
name);
8941 #if defined(AST_MISDN_ENHANCEMENTS)
8950 static void misdn_cc_handle_T_remote_user_free(
struct misdn_bchannel *bc)
8952 struct misdn_cc_record *cc_record;
8953 struct misdn_cc_notify notify;
8957 cc_record = misdn_cc_find_by_bc(bc);
8959 if (cc_record->party_a_free) {
8960 notify = cc_record->remote_user_free;
8963 bc->
fac_out.Function = Fac_CCBS_T_Suspend;
8964 bc->
fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
8968 notify = cc_record->b_free;
8970 record_id = cc_record->record_id;
8972 if (notify.context[0]) {
8974 misdn_cc_pbx_notify(record_id, ¬ify);
8982 #if defined(AST_MISDN_ENHANCEMENTS)
8992 static void misdn_cc_handle_remote_user_free(
int port,
const struct FacParm *facility)
8994 struct misdn_cc_record *cc_record;
8995 struct misdn_cc_notify notify;
8999 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSRemoteUserFree.CCBSReference);
9001 notify = cc_record->remote_user_free;
9002 record_id = cc_record->record_id;
9004 misdn_cc_pbx_notify(record_id, ¬ify);
9011 #if defined(AST_MISDN_ENHANCEMENTS)
9021 static void misdn_cc_handle_b_free(
int port,
const struct FacParm *facility)
9023 struct misdn_cc_record *cc_record;
9024 struct misdn_cc_notify notify;
9028 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSBFree.CCBSReference);
9029 if (cc_record && cc_record->b_free.context[0]) {
9031 notify = cc_record->b_free;
9032 record_id = cc_record->record_id;
9034 misdn_cc_pbx_notify(record_id, ¬ify);
9053 #if defined(AST_MISDN_ENHANCEMENTS)
9054 const char *diagnostic_msg;
9055 struct misdn_cc_record *cc_record;
9062 switch (bc->
fac_in.Function) {
9063 #if defined(AST_MISDN_ENHANCEMENTS)
9064 case Fac_ActivationDiversion:
9065 switch (bc->
fac_in.u.ActivationDiversion.ComponentType) {
9066 case FacComponent_Result:
9076 case Fac_DeactivationDiversion:
9077 switch (bc->
fac_in.u.DeactivationDiversion.ComponentType) {
9078 case FacComponent_Result:
9088 case Fac_ActivationStatusNotificationDiv:
9093 case Fac_DeactivationStatusNotificationDiv:
9098 case Fac_InterrogationDiversion:
9101 case Fac_InterrogateServedUserNumbers:
9105 case Fac_DiversionInformation:
9109 case Fac_CallDeflection:
9110 if (ch && ch->
ast) {
9111 switch (bc->
fac_in.u.CallDeflection.ComponentType) {
9112 case FacComponent_Invoke:
9119 if (bc->
fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
9121 bc->
fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser
9128 memset(&party_id, 0,
sizeof(party_id));
9129 misdn_PartyNumber_extract(&party_id,
9130 &bc->
fac_in.u.CallDeflection.Component.Invoke.Deflection.Party);
9149 bc->
fac_out.Function = Fac_RESULT;
9150 bc->
fac_out.u.RESULT.InvokeID = bc->
fac_in.u.CallDeflection.InvokeID;
9152 bc->
fac_out.Function = Fac_CallDeflection;
9153 bc->
fac_out.u.CallDeflection.InvokeID = bc->
fac_in.u.CallDeflection.InvokeID;
9154 bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Result;
9163 case FacComponent_Result:
9179 case Fac_CallRerouteing:
9184 case Fac_DivertingLegInformation1:
9186 bc->div_leg_3_rx_wanted = 0;
9187 if (ch && ch->
ast) {
9189 diversion_reason_to_misdn(bc->
fac_in.u.DivertingLegInformation1.DiversionReason);
9190 if (bc->
fac_in.u.DivertingLegInformation1.DivertedToPresent) {
9191 misdn_PresentedNumberUnscreened_extract(&bc->
redirecting.
to,
9192 &bc->
fac_in.u.DivertingLegInformation1.DivertedTo);
9205 bc->div_leg_3_rx_wanted = 1;
9208 case Fac_DivertingLegInformation2:
9213 bc->div_leg_3_tx_pending = 1;
9214 if (ch && ch->
ast) {
9233 diversion_reason_to_misdn(bc->
fac_in.u.DivertingLegInformation2.DiversionReason);
9235 if (bc->
fac_in.u.DivertingLegInformation2.DivertingPresent) {
9238 &bc->
fac_in.u.DivertingLegInformation2.Diverting);
9245 if (bc->
fac_in.u.DivertingLegInformation2.OriginalCalledPresent) {
9253 chan_misdn_log(0, bc->
port,
" --> Expected in a SETUP message: facility type:0x%04X\n",
9258 case Fac_DivertingLegInformation3:
9260 if (bc->div_leg_3_rx_wanted) {
9261 bc->div_leg_3_rx_wanted = 0;
9263 if (ch && ch->
ast) {
9265 bc->
fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
9276 if (ch && ch->
ast) {
9284 bc->
fac_in.u.CDeflection.PresentationAllowed
9288 (
char *) bc->
fac_in.u.CDeflection.DeflectedToNumber,
9309 case Fac_AOCDCurrency:
9310 if (ch && ch->
ast) {
9317 case Fac_AOCDChargingUnit:
9318 if (ch && ch->
ast) {
9319 bc->
AOCDtype = Fac_AOCDChargingUnit;
9325 #if defined(AST_MISDN_ENHANCEMENTS)
9327 diagnostic_msg = misdn_to_str_error_code(bc->
fac_in.u.ERROR.errorValue);
9334 if (ch && ch->peer) {
9335 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9342 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.ERROR.invokeId);
9344 cc_record->outstanding_message = 0;
9345 cc_record->error_code = bc->
fac_in.u.ERROR.errorValue;
9350 diagnostic_msg = misdn_to_str_reject_code(bc->
fac_in.u.REJECT.Code);
9357 if (ch && ch->peer) {
9358 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9364 if (bc->
fac_in.u.REJECT.InvokeIDPresent) {
9366 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.REJECT.InvokeID);
9368 cc_record->outstanding_message = 0;
9369 cc_record->reject_code = bc->
fac_in.u.REJECT.Code;
9376 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.RESULT.InvokeID);
9378 cc_record->outstanding_message = 0;
9383 case Fac_EctExecute:
9386 case Fac_ExplicitEctExecute:
9389 case Fac_EctLinkIdRequest:
9393 case Fac_SubaddressTransfer:
9396 case Fac_RequestSubaddress:
9425 if (!ch || !ch->
ast) {
9437 if (!ch || !ch->
ast) {
9453 if (ch && ch->
ast && bc->
fac_in.u.EctInform.RedirectionPresent) {
9455 memset(&party_id, 0,
sizeof(party_id));
9456 misdn_PresentedNumberUnscreened_extract(&party_id,
9457 &bc->
fac_in.u.EctInform.Redirection);
9471 (bc->
fac_in.u.EctInform.Status == 0 )
9478 case Fac_EctLoopTest:
9483 case Fac_CallInfoRetain:
9488 if (ch && ch->peer) {
9490 if (ch->record_id == -1) {
9491 cc_record = misdn_cc_new();
9502 cc_record = misdn_cc_find_by_id(ch->record_id);
9504 if (cc_record->ptp && cc_record->mode.ptp.bc) {
9513 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9522 new_record_id = misdn_cc_record_id_new();
9523 if (new_record_id < 0) {
9526 cc_record->record_id = new_record_id;
9527 ch->record_id = new_record_id;
9530 cc_record->port = bc->
port;
9531 memset(&cc_record->mode, 0,
sizeof(cc_record->mode));
9532 cc_record->mode.ptmp.linkage_id = bc->
fac_in.u.CallInfoRetain.CallLinkageID;
9533 cc_record->invoke_id = ++misdn_invoke_id;
9534 cc_record->activated = 0;
9535 cc_record->outstanding_message = 0;
9536 cc_record->activation_requested = 0;
9537 cc_record->error_code = FacError_None;
9538 cc_record->reject_code = FacReject_None;
9539 memset(&cc_record->remote_user_free, 0,
sizeof(cc_record->remote_user_free));
9540 memset(&cc_record->b_free, 0,
sizeof(cc_record->b_free));
9541 cc_record->time_created = time(NULL);
9551 cc_record = misdn_cc_new();
9555 ch->record_id = cc_record->record_id;
9557 cc_record->port = bc->
port;
9558 cc_record->mode.ptmp.linkage_id = bc->
fac_in.u.CallInfoRetain.CallLinkageID;
9561 cc_record->redial.caller = bc->
caller;
9562 cc_record->redial.dialed = bc->
dialed;
9563 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9564 cc_record->redial.capability = bc->
capability;
9565 cc_record->redial.hdlc = bc->
hdlc;
9570 if (ch->record_id != -1) {
9571 snprintf(buf,
sizeof(buf),
"%ld", ch->record_id);
9575 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9580 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9585 case Fac_CCBS_T_Call:
9595 chan_misdn_log(0, bc->
port,
" --> Expected in a SETUP message: facility type:0x%04X\n",
9600 case Fac_CCBSDeactivate:
9601 switch (bc->
fac_in.u.CCBSDeactivate.ComponentType) {
9602 case FacComponent_Result:
9604 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBSDeactivate.InvokeID);
9606 cc_record->outstanding_message = 0;
9619 cc_record = misdn_cc_find_by_reference(bc->
port, bc->
fac_in.u.CCBSErase.CCBSReference);
9621 misdn_cc_delete(cc_record);
9625 case Fac_CCBSRemoteUserFree:
9626 misdn_cc_handle_remote_user_free(bc->
port, &bc->
fac_in);
9629 misdn_cc_handle_b_free(bc->
port, &bc->
fac_in);
9631 case Fac_CCBSStatusRequest:
9632 misdn_cc_handle_ccbs_status_request(bc->
port, &bc->
fac_in);
9634 case Fac_EraseCallLinkageID:
9636 cc_record = misdn_cc_find_by_linkage(bc->
port,
9637 bc->
fac_in.u.EraseCallLinkageID.CallLinkageID);
9638 if (cc_record && !cc_record->activation_requested) {
9644 misdn_cc_delete(cc_record);
9648 case Fac_CCBSStopAlerting:
9651 case Fac_CCBSRequest:
9652 case Fac_CCNRRequest:
9653 switch (bc->
fac_in.u.CCBSRequest.ComponentType) {
9654 case FacComponent_Result:
9656 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBSRequest.InvokeID);
9657 if (cc_record && !cc_record->ptp) {
9658 cc_record->outstanding_message = 0;
9659 cc_record->activated = 1;
9660 cc_record->mode.ptmp.recall_mode = bc->
fac_in.u.CCBSRequest.Component.Result.RecallMode;
9661 cc_record->mode.ptmp.reference_id = bc->
fac_in.u.CCBSRequest.Component.Result.CCBSReference;
9673 case Fac_CCBSInterrogate:
9674 case Fac_CCNRInterrogate:
9677 case Fac_StatusRequest:
9682 case Fac_CCBS_T_Suspend:
9683 case Fac_CCBS_T_Resume:
9687 case Fac_CCBS_T_RemoteUserFree:
9688 misdn_cc_handle_T_remote_user_free(bc);
9690 case Fac_CCBS_T_Available:
9695 if (ch && ch->peer) {
9699 if (ch->record_id == -1) {
9700 cc_record = misdn_cc_new();
9707 cc_record = misdn_cc_find_by_id(ch->record_id);
9709 if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
9714 chan_misdn_log(1, bc->
port,
" --> Call-completion request retention option is enabled\n");
9718 if (cc_record->ptp && cc_record->mode.ptp.bc) {
9728 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9737 new_record_id = misdn_cc_record_id_new();
9738 if (new_record_id < 0) {
9741 cc_record->record_id = new_record_id;
9742 ch->record_id = new_record_id;
9745 cc_record->port = bc->
port;
9746 memset(&cc_record->mode, 0,
sizeof(cc_record->mode));
9747 cc_record->invoke_id = ++misdn_invoke_id;
9748 cc_record->activated = 0;
9749 cc_record->outstanding_message = 0;
9750 cc_record->activation_requested = 0;
9751 cc_record->error_code = FacError_None;
9752 cc_record->reject_code = FacReject_None;
9753 memset(&cc_record->remote_user_free, 0,
sizeof(cc_record->remote_user_free));
9754 memset(&cc_record->b_free, 0,
sizeof(cc_record->b_free));
9755 cc_record->time_created = time(NULL);
9765 cc_record = misdn_cc_new();
9769 ch->record_id = cc_record->record_id;
9771 cc_record->port = bc->
port;
9774 cc_record->redial.caller = bc->
caller;
9775 cc_record->redial.dialed = bc->
dialed;
9776 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9777 cc_record->redial.capability = bc->
capability;
9778 cc_record->redial.hdlc = bc->
hdlc;
9783 if (ch->record_id != -1 && set_id) {
9784 snprintf(buf,
sizeof(buf),
"%ld", ch->record_id);
9788 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9793 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9798 case Fac_CCBS_T_Request:
9799 case Fac_CCNR_T_Request:
9800 switch (bc->
fac_in.u.CCBS_T_Request.ComponentType) {
9801 case FacComponent_Result:
9803 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBS_T_Request.InvokeID);
9804 if (cc_record && cc_record->ptp) {
9805 cc_record->outstanding_message = 0;
9806 cc_record->activated = 1;
9807 cc_record->mode.ptp.retention_enabled =
9808 cc_record->mode.ptp.requested_retention
9809 ? bc->
fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
9816 case FacComponent_Invoke:
9861 #if defined(AST_MISDN_ENHANCEMENTS)
9862 struct misdn_cc_record *cc_record;
9876 "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
9883 if (debuglevel == 1) {
9978 memset(&fr, 0,
sizeof(fr));
10034 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10044 "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10045 "\tMaybe you want to add an 'i' extension to catch this case.\n",
10078 memset(&fr, 0,
sizeof(fr));
10107 int append_msn = 0;
10110 switch (ch->
state) {
10156 snprintf(tmp,
sizeof(tmp),
"%d", exceed);
10213 for (i = 0; i <
ARRAY_LEN(allowed_bearers_array); ++i) {
10214 if (allowed_bearers_array[i].cap == bc->
capability) {
10217 if (allowed_bearers_array[i].deprecated) {
10219 allowed_bearers_array[i].
name);
10225 if (i ==
ARRAY_LEN(allowed_bearers_array)) {
10240 if (bc->
fac_in.Function != Fac_None) {
10283 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10294 "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10295 "\tMaybe you want to add an 'i' extension to catch this case.\n",
10369 #if defined(AST_MISDN_ENHANCEMENTS)
10371 if (bc->
fac_in.Function != Fac_None) {
10381 bc->
fac_out.Function = Fac_None;
10393 if (bc->
fac_in.Function != Fac_None) {
10419 if (bc->
fac_in.Function != Fac_None) {
10434 if (bc->
fac_in.Function != Fac_None) {
10459 if (bc->
fac_in.Function != Fac_None) {
10466 cb_log(7, bc->
port,
" --> Set State Ringing\n");
10469 cb_log(1, bc->
port,
"Starting Tones, we have inband Data\n");
10472 cb_log(3, bc->
port,
" --> We have no inband Data, the other end must create ringing\n");
10474 cb_log(1, bc->
port,
" --> The other end can not do ringing eh ?.. we must do all ourself..");
10481 if (bc->
fac_in.Function != Fac_None) {
10484 #if defined(AST_MISDN_ENHANCEMENTS)
10485 if (bc->div_leg_3_rx_wanted) {
10486 bc->div_leg_3_rx_wanted = 0;
10505 #if defined(AST_MISDN_ENHANCEMENTS)
10506 if (ch->record_id != -1) {
10514 cc_record = misdn_cc_find_by_id(ch->record_id);
10516 if (cc_record->ptp && cc_record->mode.ptp.bc) {
10518 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
10522 misdn_cc_delete(cc_record);
10525 ch->record_id = -1;
10527 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID,
"");
10563 if (bc->
fac_in.Function != Fac_None) {
10600 if (bc->
fac_in.Function != Fac_None) {
10607 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
10637 " --> no Ch, so we've already released. (%s)\n",
10642 if (bc->
fac_in.Function != Fac_None) {
10662 if (bc->
fac_in.Function != Fac_None) {
10670 #if defined(AST_MISDN_ENHANCEMENTS)
10677 cc_record = misdn_cc_find_by_bc(bc);
10680 misdn_cc_delete(cc_record);
10686 " --> no Ch, so we've already released. (%s)\n",
10694 switch (ch->
state) {
10711 int (*generate)(
struct ast_channel *chan,
void *tmp,
int datalen,
int samples);
10727 if (tone_len < 0 || tone_len > 512) {
10732 res = generate(ast, tmp, tone_len, tone_len);
10751 memset(&frame, 0,
sizeof(frame));
10766 struct pollfd pfd = { .fd = ch->
pipe[1], .events = POLLOUT };
10780 if (pfd.revents & POLLOUT) {
10799 switch (ch->
state) {
10830 chan_misdn_log(1, bc->
port,
" --> in state cleaning .. so ignoring, the stack should clean it for us\n");
10872 if (!hold_allowed) {
10914 if (!ch || !ch->
ast) {
10917 switch (ch->
state) {
10944 if (!ch || !ch->
ast) {
10956 if (!ch || !ch->
ast) {
10971 if (bc->
fac_in.Function == Fac_None) {
10973 chan_misdn_log(0, bc->
port,
" --> Missing facility ie or unknown facility ie contents.\n");
11001 #if defined(AST_MISDN_ENHANCEMENTS)
11015 static int misdn_cc_read(
struct ast_channel *chan,
const char *function_name,
11016 char *function_args,
char *buf,
size_t size)
11019 struct misdn_cc_record *cc_record;
11043 if (!isdigit(*
args.cc_id)) {
11044 ast_log(
LOG_ERROR,
"Function '%s' call completion record ID must be numeric.\n",
11056 cc_record = misdn_cc_find_by_id(atoi(
args.cc_id));
11058 if (!strcasecmp(
"a-all",
args.get_name)) {
11059 snprintf(buf, size,
"\"%s\" <%s>", cc_record->redial.caller.name,
11060 cc_record->redial.caller.number);
11061 }
else if (!strcasecmp(
"a-name",
args.get_name)) {
11063 }
else if (!strncasecmp(
"a-num",
args.get_name, 5)) {
11065 }
else if (!strcasecmp(
"a-ton",
args.get_name)) {
11066 snprintf(buf, size,
"%d",
11069 }
else if (!strncasecmp(
"a-pres",
args.get_name, 6)) {
11073 }
else if (!strcasecmp(
"a-busy",
args.get_name)) {
11075 }
else if (!strncasecmp(
"b-num",
args.get_name, 5)) {
11077 }
else if (!strcasecmp(
"b-ton",
args.get_name)) {
11078 snprintf(buf, size,
"%d",
11081 }
else if (!strcasecmp(
"port",
args.get_name)) {
11082 snprintf(buf, size,
"%d", cc_record->port);
11083 }
else if (!strcasecmp(
"available-notify-priority",
args.get_name)) {
11084 snprintf(buf, size,
"%d", cc_record->remote_user_free.priority);
11085 }
else if (!strcasecmp(
"available-notify-exten",
args.get_name)) {
11087 }
else if (!strcasecmp(
"available-notify-context",
args.get_name)) {
11089 }
else if (!strcasecmp(
"busy-notify-priority",
args.get_name)) {
11090 snprintf(buf, size,
"%d", cc_record->b_free.priority);
11091 }
else if (!strcasecmp(
"busy-notify-exten",
args.get_name)) {
11093 }
else if (!strcasecmp(
"busy-notify-context",
args.get_name)) {
11097 ast_log(
LOG_ERROR,
"Function '%s': Unknown what-to-get '%s'.\n", function_name,
args.get_name);
11107 #if defined(AST_MISDN_ENHANCEMENTS)
11109 .
name =
"mISDN_CC",
11110 .synopsis =
"Get call completion record information.",
11111 .syntax =
"mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)",
11113 "mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)\n"
11114 "The following can be retrieved:\n"
11115 "\"a-num\", \"a-name\", \"a-all\", \"a-ton\", \"a-pres\", \"a-busy\",\n"
11116 "\"b-num\", \"b-ton\", \"port\",\n"
11117 " User-A is available for call completion:\n"
11118 " \"available-notify-priority\",\n"
11119 " \"available-notify-exten\",\n"
11120 " \"available-notify-context\",\n"
11121 " User-A is busy:\n"
11122 " \"busy-notify-priority\",\n"
11123 " \"busy-notify-exten\",\n"
11124 " \"busy-notify-context\"\n",
11125 .read = misdn_cc_read,
11145 if (!g_config_initialized) {
11155 #if defined(AST_MISDN_ENHANCEMENTS)
11172 #if defined(AST_MISDN_ENHANCEMENTS)
11173 misdn_cc_destroy();
11182 int ntflags = 0, ntkc = 0;
11183 char ports[256] =
"";
11194 if (max_ports <= 0) {
11203 g_config_initialized = 1;
11205 #if defined(AST_MISDN_ENHANCEMENTS)
11209 misdn_debug =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11210 if (!misdn_debug) {
11214 misdn_ports =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11215 if (!misdn_ports) {
11222 misdn_debug[i] = misdn_debug[0];
11223 misdn_ports[i] = i;
11226 misdn_debug_only =
ast_calloc(max_ports + 1,
sizeof(
int));
11227 if (!misdn_debug_only) {
11239 misdn_in_calls =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11240 if (!misdn_in_calls) {
11247 misdn_out_calls =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11248 if (!misdn_out_calls) {
11258 misdn_in_calls[i] = 0;
11259 misdn_out_calls[i] = 0;
11291 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
11292 "Sets mISDN opts. and optargs\n"
11294 "The available options are:\n"
11295 " a - Have Asterisk detect DTMF tones on called channel\n"
11296 " c - Make crypted outgoing call, optarg is keyindex\n"
11297 " d - Send display text to called phone, text is the optarg\n"
11298 " e - Perform echo cancellation on this channel,\n"
11299 " takes taps as optarg (32,64,128,256)\n"
11300 " e! - Disable echo cancellation on this channel\n"
11301 " f - Enable fax detection\n"
11302 " h - Make digital outgoing call\n"
11303 " h1 - Make HDLC mode digital outgoing call\n"
11304 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
11305 " they will be transported inband.\n"
11306 " jb - Set jitter buffer length, optarg is length\n"
11307 " jt - Set jitter buffer upper threshold, optarg is threshold\n"
11308 " jn - Disable jitter buffer\n"
11309 " n - Disable mISDN DSP on channel.\n"
11310 " Disables: echo cancel, DTMF detection, and volume control.\n"
11311 " p - Caller ID presentation,\n"
11312 " optarg is either 'allowed' or 'restricted'\n"
11313 " s - Send Non-inband DTMF as inband\n"
11314 " vr - Rx gain control, optarg is gain\n"
11315 " vt - Tx gain control, optarg is gain\n"
11320 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
11321 "Sends the Facility Message FACILITY_TYPE with \n"
11322 "the given Arguments to the current ISDN Channel\n"
11323 "Supported Facilities are:\n"
11325 "type=calldeflect args=Nr where to deflect\n"
11326 #
if defined(AST_MISDN_ENHANCEMENTS)
11327 "type=callrerouting args=Nr where to deflect\n"
11333 "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n"
11334 "Checks if the L2 and L1 are up on either the given <port> or\n"
11335 "on the ports in the group with <groupname>\n"
11336 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
11337 "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
11339 "This application, ensures the L1/L2 state of the Ports in a group\n"
11340 "it is intended to make the pmp_l1_check option redundant and to\n"
11341 "fix a buggy switch config from your provider\n"
11343 "a sample dialplan would look like:\n\n"
11344 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
11345 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
11348 #if defined(AST_MISDN_ENHANCEMENTS)
11350 "misdn_command(<command>[,<options>])\n"
11351 "The following commands are defined:\n"
11353 " Setup mISDN support for call completion\n"
11354 " Must call before doing any Dial() involving call completion.\n"
11355 "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11356 " Request Call Completion No Reply activation\n"
11357 "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11358 " Request Call Completion Busy Subscriber activation\n"
11359 "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11360 " Set the dialplan location to notify when User-B is available but User-A is busy.\n"
11361 " Setting this dialplan location is optional.\n"
11362 "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n"
11363 " Set the busy status of call completion User-A\n"
11364 "cc-deactivate,${MISDN_CC_RECORD_ID}\n"
11365 " Deactivate the identified call completion request\n"
11367 "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n"
11368 "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n"
11369 "activation request.\n"
11370 "MISDN_ERROR_MSG is set to a descriptive message on error.\n"
11384 chan_misdn_log(4, 0,
"Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
11389 chan_misdn_log(0, 0,
"-- mISDN Channel Driver Registered --\n");
11405 #if defined(AST_MISDN_ENHANCEMENTS)
11415 #if defined(AST_MISDN_ENHANCEMENTS)
11416 static void misdn_cc_caller_destroy(
void *obj)
11422 #if defined(AST_MISDN_ENHANCEMENTS)
11423 static struct misdn_cc_caller *misdn_cc_caller_alloc(
struct ast_channel *chan)
11425 struct misdn_cc_caller *cc_caller;
11427 if (!(cc_caller =
ao2_alloc(
sizeof(*cc_caller), misdn_cc_caller_destroy))) {
11431 cc_caller->chan = chan;
11437 #if defined(AST_MISDN_ENHANCEMENTS)
11448 static int misdn_command_cc_initialize(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11450 struct misdn_cc_caller *cc_caller;
11453 if (!(cc_caller = misdn_cc_caller_alloc(chan))) {
11465 datastore->
data = cc_caller;
11478 #if defined(AST_MISDN_ENHANCEMENTS)
11493 static int misdn_command_cc_deactivate(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11496 const char *error_str;
11497 struct misdn_cc_record *cc_record;
11501 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID})\n";
11503 if (
ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
11507 record_id = atol(subcommand->arg[0]);
11510 cc_record = misdn_cc_find_by_id(record_id);
11511 if (cc_record && 0 <= cc_record->port) {
11512 if (cc_record->ptp) {
11513 if (cc_record->mode.ptp.bc) {
11515 bc = cc_record->mode.ptp.bc;
11516 bc->
fac_out.Function = Fac_None;
11520 misdn_cc_delete(cc_record);
11521 }
else if (cc_record->activated) {
11522 cc_record->error_code = FacError_None;
11523 cc_record->reject_code = FacReject_None;
11524 cc_record->invoke_id = ++misdn_invoke_id;
11525 cc_record->outstanding_message = 1;
11529 dummy.fac_out.Function = Fac_CCBSDeactivate;
11530 dummy.fac_out.u.CCBSDeactivate.InvokeID = cc_record->invoke_id;
11531 dummy.fac_out.u.CCBSDeactivate.ComponentType = FacComponent_Invoke;
11532 dummy.fac_out.u.CCBSDeactivate.Component.Invoke.CCBSReference = cc_record->mode.ptmp.reference_id;
11542 misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
11545 cc_record = misdn_cc_find_by_id(record_id);
11547 if (cc_record->port < 0) {
11550 }
else if (cc_record->outstanding_message) {
11551 cc_record->outstanding_message = 0;
11552 error_str = misdn_no_response_from_network;
11553 }
else if (cc_record->reject_code != FacReject_None) {
11554 error_str = misdn_to_str_reject_code(cc_record->reject_code);
11555 }
else if (cc_record->error_code != FacError_None) {
11556 error_str = misdn_to_str_error_code(cc_record->error_code);
11561 misdn_cc_delete(cc_record);
11567 ast_verb(1,
"%s(%s) diagnostic '%s' on channel %s\n",
11568 misdn_command_name, subcommand->name, error_str, chan->
name);
11576 #if defined(AST_MISDN_ENHANCEMENTS)
11591 static int misdn_command_cc_a_busy(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11595 struct misdn_cc_record *cc_record;
11598 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<yes/no>)\n";
11600 if (
ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
11604 record_id = atol(subcommand->arg[0]);
11606 if (
ast_true(subcommand->arg[1])) {
11608 }
else if (
ast_false(subcommand->arg[1])) {
11616 cc_record = misdn_cc_find_by_id(record_id);
11617 if (cc_record && cc_record->party_a_free != party_a_free) {
11619 cc_record->party_a_free = party_a_free;
11621 if (cc_record->ptp && cc_record->mode.ptp.bc) {
11622 cc_record->error_code = FacError_None;
11623 cc_record->reject_code = FacReject_None;
11626 bc = cc_record->mode.ptp.bc;
11627 if (cc_record->party_a_free) {
11628 bc->
fac_out.Function = Fac_CCBS_T_Resume;
11629 bc->
fac_out.u.CCBS_T_Resume.InvokeID = ++misdn_invoke_id;
11631 bc->
fac_out.Function = Fac_CCBS_T_Suspend;
11632 bc->
fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
11646 #if defined(AST_MISDN_ENHANCEMENTS)
11661 static int misdn_command_cc_b_free(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11668 struct misdn_cc_record *cc_record;
11670 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
11673 for (index = 0; index < 4; ++index) {
11681 if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
11686 record_id = atol(subcommand->arg[0]);
11687 context = subcommand->arg[1];
11688 exten = subcommand->arg[2];
11689 priority = atoi(subcommand->arg[3]);
11692 cc_record = misdn_cc_find_by_id(record_id);
11695 ast_copy_string(cc_record->b_free.context, context,
sizeof(cc_record->b_free.context));
11696 ast_copy_string(cc_record->b_free.exten, exten,
sizeof(cc_record->b_free.exten));
11697 cc_record->b_free.priority = priority;
11705 #if defined(AST_MISDN_ENHANCEMENTS)
11706 struct misdn_cc_request {
11707 enum FacFunction ptmp;
11708 enum FacFunction
ptp;
11712 #if defined(AST_MISDN_ENHANCEMENTS)
11729 static int misdn_command_cc_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand,
const struct misdn_cc_request *request)
11732 int request_retention;
11737 const char *error_str;
11738 struct misdn_cc_record *cc_record;
11743 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
11746 for (index = 0; index < 4; ++index) {
11754 if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
11759 record_id = atol(subcommand->arg[0]);
11760 context = subcommand->arg[1];
11761 exten = subcommand->arg[2];
11762 priority = atoi(subcommand->arg[3]);
11765 cc_record = misdn_cc_find_by_id(record_id);
11769 sizeof(cc_record->remote_user_free.context));
11771 sizeof(cc_record->remote_user_free.exten));
11772 cc_record->remote_user_free.priority = priority;
11774 if (0 <= cc_record->port) {
11775 if (cc_record->ptp) {
11776 if (!cc_record->mode.ptp.bc) {
11777 bc = misdn_lib_get_register_bc(cc_record->port);
11779 cc_record->mode.ptp.bc = bc;
11780 cc_record->error_code = FacError_None;
11781 cc_record->reject_code = FacReject_None;
11782 cc_record->invoke_id = ++misdn_invoke_id;
11783 cc_record->outstanding_message = 1;
11784 cc_record->activation_requested = 1;
11787 &request_retention,
sizeof(request_retention));
11788 cc_record->mode.ptp.requested_retention = request_retention ? 1 : 0;
11791 bc->
fac_out.Function = request->ptp;
11792 bc->
fac_out.u.CCBS_T_Request.InvokeID = cc_record->invoke_id;
11793 bc->
fac_out.u.CCBS_T_Request.ComponentType = FacComponent_Invoke;
11794 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Q931ie =
11795 cc_record->redial.setup_bc_hlc_llc;
11796 memset(&
id, 0,
sizeof(
id));
11797 id.number_plan = cc_record->redial.dialed.number_plan;
11798 id.number_type = cc_record->redial.dialed.number_type;
11800 sizeof(
id.number));
11801 misdn_Address_fill(
11802 &bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Destination,
11804 misdn_Address_fill(
11805 &bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Originating,
11806 &cc_record->redial.caller);
11807 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1;
11808 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator =
11809 (cc_record->redial.caller.presentation != 0) ? 0 : 1;
11810 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.RetentionSupported =
11811 request_retention ? 1 : 0;
11819 cc_record->error_code = FacError_None;
11820 cc_record->reject_code = FacReject_None;
11821 cc_record->invoke_id = ++misdn_invoke_id;
11822 cc_record->outstanding_message = 1;
11823 cc_record->activation_requested = 1;
11828 dummy.fac_out.Function = request->ptmp;
11829 dummy.fac_out.u.CCBSRequest.InvokeID = cc_record->invoke_id;
11830 dummy.fac_out.u.CCBSRequest.ComponentType = FacComponent_Invoke;
11831 dummy.fac_out.u.CCBSRequest.Component.Invoke.CallLinkageID =
11832 cc_record->mode.ptmp.linkage_id;
11843 misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
11846 cc_record = misdn_cc_find_by_id(record_id);
11848 if (!cc_record->activated) {
11849 if (cc_record->port < 0) {
11851 error_str =
"No port number";
11852 }
else if (cc_record->outstanding_message) {
11853 cc_record->outstanding_message = 0;
11854 error_str = misdn_no_response_from_network;
11855 }
else if (cc_record->reject_code != FacReject_None) {
11856 error_str = misdn_to_str_reject_code(cc_record->reject_code);
11857 }
else if (cc_record->error_code != FacError_None) {
11858 error_str = misdn_to_str_error_code(cc_record->error_code);
11859 }
else if (cc_record->ptp) {
11860 if (cc_record->mode.ptp.bc) {
11861 error_str =
"Call-completion already requested";
11863 error_str =
"Could not allocate call-completion signaling link";
11867 error_str =
"Unexpected error";
11871 if (cc_record->ptp && cc_record->mode.ptp.bc) {
11873 bc = cc_record->mode.ptp.bc;
11874 bc->
fac_out.Function = Fac_None;
11878 misdn_cc_delete(cc_record);
11883 error_str = misdn_cc_record_not_found;
11887 ast_verb(1,
"%s(%s) diagnostic '%s' on channel %s\n",
11888 misdn_command_name, subcommand->name, error_str, chan->
name);
11899 #if defined(AST_MISDN_ENHANCEMENTS)
11914 static int misdn_command_ccbs_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11916 static const struct misdn_cc_request request = {
11917 .ptmp = Fac_CCBSRequest,
11918 .ptp = Fac_CCBS_T_Request
11921 return misdn_command_cc_request(chan, subcommand, &request);
11925 #if defined(AST_MISDN_ENHANCEMENTS)
11940 static int misdn_command_ccnr_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11942 static const struct misdn_cc_request request = {
11943 .ptmp = Fac_CCNRRequest,
11944 .ptp = Fac_CCNR_T_Request
11947 return misdn_command_cc_request(chan, subcommand, &request);
11951 #if defined(AST_MISDN_ENHANCEMENTS)
11952 struct misdn_command_table {
11957 int (*func)(
struct ast_channel *chan,
struct misdn_command_args *subcommand);
11962 static const struct misdn_command_table misdn_commands[] = {
11965 {
"cc-initialize", misdn_command_cc_initialize, 0 },
11966 {
"cc-deactivate", misdn_command_cc_deactivate, 0 },
11967 {
"cc-a-busy", misdn_command_cc_a_busy, 0 },
11968 {
"cc-b-free", misdn_command_cc_b_free, 0 },
11969 {
"ccbs-request", misdn_command_ccbs_request, 0 },
11970 {
"ccnr-request", misdn_command_ccnr_request, 0 },
11975 #if defined(AST_MISDN_ENHANCEMENTS)
11986 static int misdn_command_exec(
struct ast_channel *chan,
const char *data)
11990 struct misdn_command_args subcommand;
12006 for (index = 0; index <
ARRAY_LEN(misdn_commands); ++index) {
12007 if (strcasecmp(misdn_commands[index].
name, subcommand.name) == 0) {
12008 strcpy(subcommand.name, misdn_commands[index].name);
12009 if (misdn_commands[index].misdn_only
12010 && strcasecmp(chan->
tech->
type, misdn_type) != 0) {
12012 "%s(%s) only makes sense with %s channels!\n",
12013 misdn_command_name, subcommand.name, misdn_type);
12016 return misdn_commands[index].func(chan, &subcommand);
12039 if (strcasecmp(chan->
tech->
type, misdn_type)) {
12040 ast_log(
LOG_WARNING,
"misdn_facility only makes sense with %s channels!\n", misdn_type);
12045 ast_log(
LOG_WARNING,
"misdn_facility requires arguments: facility_type[,<args>]\n");
12053 ast_log(
LOG_WARNING,
"misdn_facility requires arguments: facility_type[,<args>]\n");
12057 if (!strcasecmp(
args.facility_type,
"calldeflect")) {
12062 #if defined(AST_MISDN_ENHANCEMENTS)
12063 max_len =
sizeof(ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
12064 if (max_len < strlen(
args.arg[0])) {
12066 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12070 ch->
bc->
fac_out.Function = Fac_CallDeflection;
12071 ch->
bc->
fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
12072 ch->
bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
12073 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
12074 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
12075 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;
12076 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(
args.arg[0]);
12077 strcpy((
char *) ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number,
args.arg[0]);
12078 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
12082 max_len =
sizeof(ch->
bc->
fac_out.u.CDeflection.DeflectedToNumber) - 1;
12083 if (max_len < strlen(
args.arg[0])) {
12085 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12090 ch->
bc->
fac_out.u.CDeflection.PresentationAllowed = 0;
12092 strcpy((
char *) ch->
bc->
fac_out.u.CDeflection.DeflectedToNumber,
args.arg[0]);
12098 #if defined(AST_MISDN_ENHANCEMENTS)
12099 }
else if (!strcasecmp(
args.facility_type,
"callrerouteing")
12100 || !strcasecmp(
args.facility_type,
"callrerouting")) {
12105 max_len =
sizeof(ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
12106 if (max_len < strlen(
args.arg[0])) {
12108 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12112 ch->
bc->
fac_out.Function = Fac_CallRerouteing;
12113 ch->
bc->
fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
12114 ch->
bc->
fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
12116 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;
12117 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
12119 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;
12120 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(
args.arg[0]);
12121 strcpy((
char *) ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number,
args.arg[0]);
12122 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
12124 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
12127 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
12128 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
12129 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
12130 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
12131 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
12132 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
12133 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
12135 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;
12136 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;
12172 if (
args.argc != 2) {
12178 timeout = atoi(
args.timeout);
12179 port_str =
args.grouppar;
12181 if (port_str[0] ==
'g' && port_str[1] ==
':') {
12196 if (!strcasecmp(cfg_group, group)) {
12206 port = atoi(port_str);
12232 int change_jitter = 0;
12234 if (strcasecmp(chan->
tech->
type, misdn_type)) {
12235 ast_log(
LOG_WARNING,
"misdn_set_opt makes sense only with %s channels!\n", misdn_type);
12245 for (tok = strtok_r(parse,
":", &tokb);
12247 tok = strtok_r(NULL,
":", &tokb)) {
12250 if (tok[0] ==
'!') {
12271 ch->
jb_len = atoi(++tok);
12295 rxgain = atoi(++tok);
12306 txgain = atoi(++tok);
12319 keyidx = atoi(++tok);
12328 for (i = 0; i < keyidx; i++) {
12329 key =
strsep(&tmp,
",");
12345 *ch->
bc->pipeline = 0;
12351 update_pipeline_config(ch->
bc);
12365 if (strlen(tok) > 1 && tok[1] ==
'1') {
12389 if (strstr(tok,
"allowed")) {
12392 }
else if (strstr(tok,
"restricted")) {
12395 }
else if (strstr(tok,
"not_screened")) {
12410 if (change_jitter) {
12515 if (!jb || ! data) {
12524 for (i = 0; i <
len; i++) {
12527 wp = (wp != jb->
size - 1) ? wp + 1 : 0;
12529 if (wp == jb->
rp) {
12546 rp = (rp != 0) ? rp - 1 : jb->
size - 1;
12587 for (i = 0; i <
len; i++) {
12596 if (jb->
ok[rp] == 1) {
12599 rp = (rp != jb->
size - 1) ? rp + 1 : 0;
12614 chan_misdn_log(9, 0,
"misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
12632 if (!(0 <= port && port <= max_ports)) {
12633 ast_log(
LOG_WARNING,
"chan_misdn_log called with out-of-range port number! (%d)\n", port);
12636 }
else if (!(level == -1
12637 || (misdn_debug_only[port]
12638 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12639 : level <= misdn_debug[port])
12640 || (level <= misdn_debug[0] && !
ast_strlen_zero(global_tracefile)))) {
12648 snprintf(port_buf,
sizeof(port_buf),
"P[%2d] ", port);
12649 va_start(ap, tmpl);
12650 vsnprintf(buf,
sizeof(buf), tmpl, ap);
12655 }
else if (misdn_debug_only[port]
12656 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12657 : level <= misdn_debug[port]) {
12668 fp = fopen(global_tracefile,
"a+");
12670 ast_verbose(
"Error opening Tracefile: [ %s ] %s\n", global_tracefile, strerror(
errno));
12675 tmp = ctime_r(&tm, ctimebuf);
12676 p = strchr(tmp,
'\n');
12682 fputs(port_buf, fp);
static int misdn_send_text(struct ast_channel *chan, const char *text)
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
int misdn_lib_maxports_get(void)
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
static void chan_misdn_log(int level, int port, char *tmpl,...)
static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
#define AST_CAUSE_PROTOCOL_ERROR
int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
unsigned long long ast_group_t
union ast_frame_subclass subclass
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
enum sip_cc_notify_state state
void misdn_cfg_destroy(void)
static int ast_to_misdn_pres(int presentation)
static int misdn_digit_begin(struct ast_channel *chan, char digit)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int display_setup
Put a display ie in the SETUP message.
AST_CONNECTED_LINE_UPDATE_SOURCE
Connected line update source code.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
#define ast_channel_lock(chan)
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
static char exten[AST_MAX_EXTENSION]
static enum ast_bridge_result misdn_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
Main Channel structure associated with a channel.
static int stop_indicate(struct chan_list *cl)
#define AST_DEFINE_APP_ARGS_TYPE(type, arglist)
Define a structure type to hold an application's arguments.
static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
int jb_len
Jitterbuffer length.
#define AST_CLI_DEFINE(fn, txt,...)
static struct chan_list * find_hold_call(struct misdn_bchannel *bc)
char * str
Subscriber phone number (Malloced)
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
void debug_numtype(int port, int numtype, char *type)
struct FacParm fac_out
Outbound FACILITY message function type and contents.
struct ast_party_connected_line connected
Channel Connected Line ID information.
#define AST_LIST_LOCK(head)
Locks a list.
static void hanguptone_indicate(struct chan_list *cl)
static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
static const char * misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
struct chan_list * next
Next channel call record in the list.
Asterisk main include file. File version handling, generic pbx functions.
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
void misdn_lib_nt_debug_init(int flags, char *file)
int misdn_cfg_init(int this_max_ports, int reload)
static char * handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_channel * misdn_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
char ast_rd_buf[4096]
Read buffer for inbound audio from pipe[0].
char * str
Subscriber phone number (Malloced)
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
static void update_config(struct chan_list *ch)
Updates caller ID information from config.
struct ast_party_caller caller
Channel Caller ID information.
struct ast_tone_zone * zone
struct ast_set_party_id ani
char * strsep(char **str, const char *delims)
int misdn_lib_pid_restart(int pid)
int misdn_cfg_is_msn_valid(int port, char *msn)
static char * handle_cli_misdn_port_down(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_dsp * dsp
Allocated DSP controller.
static int read_config(struct chan_list *ch)
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
String manipulation functions.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Schedule callback(data) to happen when ms into the future.
int nodsp
TRUE if we will not use jollys dsp.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int need_queue_hangup
TRUE if a hangup needs to be queued.
struct ast_party_id id
Connected party ID.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
int txgain
Tx gain setting (range -8 to 8)
#define AST_CAUSE_SWITCH_CONGESTION
int ec_enable
TRUE if the echo cancellor is enabled.
enum FacFunction AOCDtype
Support for translation of data formats. translate.c.
int tone_cnt
Number of tone samples to generate.
Time-related functions and macros.
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
struct ast_party_name name
Subscriber name.
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
int uulen
User-User information string length in uu[].
void ast_dsp_free(struct ast_dsp *dsp)
#define DSP_FEATURE_DIGIT_DETECT
char uu[256]
User-User information string.
#define AST_CAUSE_UNALLOCATED
static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
int dummy
TRUE if this is a dummy BC record.
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
static char * handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void misdn_dump_chanlist(void)
Convenient Signal Processing routines.
char context[AST_MAX_CONTEXT]
static void misdn_update_caller_id(struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
static int misdn_to_ast_pres(int presentation)
static void cl_queue_chan(struct chan_list *chan)
enum misdn_cfg_elements misdn_cfg_get_elem(const char *name)
static void release_chan_early(struct chan_list *ch)
#define DEADLOCK_AVOIDANCE(lock)
static int pbx_start_chan(struct chan_list *ch)
int bframe_len
B channel speech sample data buffer size.
descriptor for a cli entry.
void manager_ec_enable(struct misdn_bchannel *bc)
static int cl_dequeue_chan(struct chan_list *chan)
struct misdn_jb * jb
Allocated jitterbuffer controller.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * manager_isdn_get_info(enum event_e event)
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
static int misdn_hangup(struct ast_channel *ast)
static void dummy(char *unused,...)
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
void ast_verbose(const char *fmt,...)
struct ast_dsp * ast_dsp_new(void)
int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun).
int cw
TRUE if call waiting.
Connected-Line/Calling/Redirecting ID info struct.
void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
int hdlc
TRUE if call made in digital HDLC mode.
void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
mISDN_REDIRECTING_REASON
Q.931 encoded redirecting reason.
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
struct ast_generator * generator
int add_out_calls(int port)
struct ast_frame frame
Inbound audio frame returned by misdn_read().
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct hold_info hold
HELD channel call information.
int jb_upper_threshold
Jitterbuffer upper threshold.
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
B channel control structure.
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
int outgoing_colp
Select what to do with outgoing COLP information.
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
enum misdn_chan_state state
static struct robin_list * robin
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Structure for a data store type.
static void config_jitterbuffer(struct chan_list *ch)
static const char * misdn_get_ch_state(struct chan_list *p)
Configuration File Parser.
char * str
Subscriber name (Malloced)
static char * handle_cli_misdn_set_tics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct chan_list * find_hold_active_call(struct misdn_bchannel *bc)
int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth)
static struct chan_list * get_chan_by_ast_name(const char *name)
char crypt_key[255]
Blowfish encryption key string (secret)
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
#define MISDN_ASTERISK_TECH_PVT(ast)
static struct ast_threadstorage buf2
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static char * handle_cli_misdn_restart_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
int capability
SETUP message bearer capability field code value.
#define ast_mutex_lock(a)
void misdn_cfg_reload(void)
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
unsigned short transfercapability
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
int misdn_cfg_get_next_port(int port)
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
static int * misdn_debug_only
Structure for a data store object.
void misdn_lib_destroy(void)
static const char * misdn_to_str_pres(int presentation)
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
struct misdn_bchannel * misdn_lib_find_held_bc(int port, int l3_id)
Find a held call's B channel record.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
I/O Management (derived from Cheops-NG)
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
static struct chan_list * cl_te
Global channel call record list head.
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
static char * handle_cli_misdn_restart_pid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
const ast_string_field linkedid
static int misdn_chan_is_valid(struct chan_list *ch)
void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Import parameters from the dialplan environment variables.
#define AST_CAUSE_INVALID_NUMBER_FORMAT
struct ast_channel * ast
Associated Asterisk channel structure.
static const char * misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
int ast_unregister_application(const char *app)
Unregister an application.
int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_PRES_NETWORK_NUMBER
static char cid_num[AST_MAX_EXTENSION]
int misdn_lib_get_maxchans(int port)
void isdn_lib_update_rxgain(struct misdn_bchannel *bc)
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
#define ast_verb(level,...)
static void chan_list_destructor(void *obj)
Indicate what information in ast_party_caller should be set.
int notxtone
TRUE if we are not to generate tones (Playtones)
static char * handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void isdn_lib_update_txgain(struct misdn_bchannel *bc)
int misdn_cap_is_speech(int cap)
static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
void isdn_lib_update_ec(struct misdn_bchannel *bc)
static int misdn_is_msn_valid(int port, const struct misdn_party_dialing *dialed)
static pthread_t misdn_tasks_thread
void get_show_stack_details(int port, char *buf)
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
String fields in structures.
char * ast_print_group(char *buf, int buflen, ast_group_t group)
print call- and pickup groups into buffer
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
#define AST_PRES_RESTRICTED
static int stop_bc_tones(struct chan_list *cl)
struct ast_set_party_id from
static void misdn_tasks_destroy(void)
static void misdn_tasks_init(void)
static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
static int misdn_l1_task(const void *vdata)
struct ast_party_id id
Caller party ID.
static char * handle_cli_misdn_port_unblock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_change_name(struct ast_channel *chan, const char *newname)
Change channel name.
static char * handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static ast_mutex_t release_lock
int misdn_inband_avail(struct misdn_bchannel *bc)
void misdn_lib_split_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
#define ast_debug(level,...)
Log a DEBUG message.
static struct ast_frame * process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
int set_presentation
TRUE if the user set the presentation restriction code.
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
void manager_ec_disable(struct misdn_bchannel *bc)
static void show_config_description(int fd, enum misdn_cfg_elements elem)
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
char display[84]
Display message that can be displayed by the user phone.
static int misdn_answer(struct ast_channel *ast)
struct ast_jb_conf * misdn_get_global_jbconf()
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
struct ast_party_id ani
Automatic Number Identification (ANI)
static char * complete_ch(struct ast_cli_args *a)
int pri
TRUE if ISDN-PRI (ISDN-BRI otherwise)
General Asterisk PBX channel definitions.
void misdn_cfg_get_desc(enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
#define AST_PRES_USER_NUMBER_UNSCREENED
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
struct ast_party_dialed::@155 number
Dialed/Called number.
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
int misdn_lib_port_block(int port)
static struct ast_frame * misdn_read(struct ast_channel *ast)
static int load_module(void)
int need_release_complete
TRUE if RELEASE_COMPLETE needs to be sent to clear a call.
static char * handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_poll(a, b, c)
static struct ast_cli_entry chan_misdn_clis[]
static void misdn_tasks_remove(int task_id)
Data structure associated with a custom dialplan function.
#define ast_register_application(app, execute, synopsis, description)
Register an application.
void misdn_lib_release(struct misdn_bchannel *bc)
Asterisk internal frame definitions.
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
static struct state_struct state_array[]
#define AST_MAX_EXTENSION
#define AST_CAUSE_NORMAL_CLEARING
Scheduler Routines (derived from cheops)
Caller Party information.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
int dropped_frame_cnt
Number of outgoing audio frames dropped since last debug gripe message.
#define ao2_ref(o, delta)
static const char * misdn_to_str_screen(int screening)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
int nt
TRUE if NT side of protocol (TE otherwise)
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
#define DSP_FEATURE_FAX_DETECT
static char * handle_cli_misdn_show_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void misdn_lib_log_ies(struct misdn_bchannel *bc)
int holded
TRUE if this channel is on hold.
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
struct ast_set_party_id id
int display_connected
Put a display ie in the CONNECT message.
#define MISDN_MAX_NUMBER_LEN
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
static char language[MAX_LANGUAGE]
int nojitter
TRUE if we will not use the jitter buffer system.
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
struct misdn_party_id caller
Originating/Caller ID information struct.
struct timeval faxdetect_tv
Starting time of fax detection with timeout when nonzero.
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
int rxgain
Rx gain setting (range -8 to 8)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static struct ast_channel_tech misdn_tech_wo_bridge
struct FacAOCDCurrency currency
char * bc_state2str(enum bchannel_state state)
enum misdn_chan_state state
State of the channel.
AST_REDIRECTING_REASON
redirecting reason codes.
int far_alerting
TRUE if we must do the ringback tones.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
static char global_tracefile[BUFFERSIZE+1]
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
int ast_cdr_update(struct ast_channel *chan)
Update CDR on a channel.
int misdn_lib_port_unblock(int port)
void misdn_lib_nt_keepcalls(int kc)
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
static char * complete_show_config(struct ast_cli_args *a)
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
int misdn_lib_is_ptp(int port)
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Export parameters to the dialplan environment variables.
char allowed_bearers[BUFFERSIZE+1]
The "allowed_bearers" string read in from /etc/asterisk/misdn.conf.
struct ast_party_dialed dialed
Dialed/Called information.
Dialed/Called information struct.
int pid
B channel process ID (1-5000)
int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
int dec
TRUE if allocate higher B channels first.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int misdn_cfg_get_next_port_spin(int port)
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
static const char * bearer2str(int cap)
char * ast_getformatname(format_t format)
Get the name of a format.
static void free_robin_list(void)
static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
static void sighandler(int sig)
int ast_channel_transfer_masquerade(struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held)
Setup a masquerade to transfer a call.
static int misdn_check_l2l1(struct ast_channel *chan, const char *data)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free's) the given sched_context structure
static char * handle_cli_misdn_port_block(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
static char * handle_cli_misdn_set_crypt_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
int misdn_lib_send_restart(int port, int channel)
#define AST_PRES_NUMBER_TYPE
static int ast_to_misdn_screen(int screening)
static struct chan_list * find_hold_call_l3(unsigned long l3_id)
static void misdn_update_remote_party(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
enum ast_channel_state _state
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Connected Line/Party information.
const ast_string_field name
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
static int misdn_overlap_dial_task(const void *data)
#define ao2_alloc(data_size, destructor_fn)
int port
Logical Layer 1 port associated with this B channel.
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
int add_in_calls(int port)
int urate
Q.931 Bearer Capability IE Layer 1 User Rate field.
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct misdn_party_dialing dialed
Dialed/Called information struct.
static void misdn_tasks_wakeup(void)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static char * handle_cli_misdn_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static const char misdn_type[]
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
static int dialtone_indicate(struct chan_list *cl)
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
static struct ast_channel_tech misdn_tech
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static int unload_module(void)
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
static char * handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int misdn_lib_get_port_up(int port)
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
int source
Information about the source of an update.
static struct allowed_bearers allowed_bearers_array[]
char macrocontext[AST_MAX_CONTEXT]
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
void misdn_cfg_update_ptp(void)
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
int active
Seems to have been intended for something to do with the jitter buffer.
#define AST_CAUSE_NUMBER_CHANGED
static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
struct misdn_bchannel * misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
static format_t capability
static void reload_config(void)
static void * misdn_tasks_thread_func(void *data)
Channel call record structure.
static char * handle_cli_misdn_send_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DATASTORE_INHERIT_FOREVER
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
int misdn_lib_port_up(int port, int check)
int misdn_lib_port_is_nt(int port)
static int update_ec_config(struct misdn_bchannel *bc)
static int * misdn_out_calls
static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
unsigned int l3id
From associated B channel: Layer 3 process ID.
int to_changed
TRUE if the redirecting.to information has changed.
#define chan_list_ref(obj, debug)
enum misdn_hold_state state
Call HOLD state.
static struct chan_list * chan_list_init(int orig)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
int channel
Original B channel number the HELD call was using.
static char cid_name[AST_MAX_EXTENSION]
enum event_response_e(* cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data)
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Indicate what information in ast_party_connected_line should be set.
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
int ast_sched_runq(struct sched_context *con)
Runs the queue.
int(* generate)(struct ast_channel *chan, void *data, int len, int samples)
static int g_config_initialized
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
void misdn_cfg_get_ports_string(char *ports)
Generate a comma separated list of all active ports.
#define AST_PRES_RESTRICTION
static void print_bearer(struct misdn_bchannel *bc)
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
int out_cause
Q.931 Cause for disconnection code (sent)
char * tag
User-set "tag".
struct ast_set_party_id id
void ast_deactivate_generator(struct ast_channel *chan)
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
struct ast_set_party_id to
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
#define AST_CAUSE_NO_ROUTE_DESTINATION
void misdn_lib_isdn_l1watcher(int port)
void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char *buf, int bufsize)
int need_release
TRUE if RELEASE needs to be sent to clear a call.
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
struct sched_context * sched_context_create(void)
New schedule context.
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
int dtmf
Last decoded DTMF digit from mISDN driver.
enum bchannel_state bc_state
Current B Channel state.
Indicate what information in ast_party_redirecting should be set.
int count
Number of times the call was redirected.
Standard Command Line Interface.
static int start_bc_tones(struct chan_list *cl)
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int faxhandled
TRUE if a fax has been detected.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
int misdn_lib_port_is_pri(int port)
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define AST_CAUSE_USER_BUSY
int misdn_lib_get_port_down(int port)
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static char * complete_debug_port(struct ast_cli_args *a)
static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
void isdn_lib_stop_dtmf(struct misdn_bchannel *bc)
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Data structure associated with a single frame of data.
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Internal Asterisk hangup causes.
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
int ec_deftaps
Number of taps in the echo cancellor when enabled.
int(* ast_sched_cb)(const void *data)
callback for a cheops scheduler A cheops scheduler callback takes a pointer with callback data and ...
int misdn_lib_port_restart(int port)
Handy terminal functions for vt* terms.
const char * data
Description of a tone.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
char * bframe
B channel speech sample data buffer.
static int * misdn_in_calls
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
Wait for a specified amount of time, looking for hangups and a condition argument.
#define AST_PRES_UNAVAILABLE
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
static void send_digit_to_chan(struct chan_list *cl, char digit)
int cause
Q.931 Cause for disconnection code (received)
static int misdn_facility_exec(struct ast_channel *chan, const char *data)
unsigned char valid
TRUE if the name information is valid/present.
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
void misdn_lib_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
int te_choose_channel
TRUE if the TE side should choose the B channel to use.
Interface to mISDN - Config.
static char context[AST_MAX_CONTEXT]
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send DTMF to a channel.
#define ast_mutex_destroy(a)
static struct robin_list * get_robin_position(char *group)
static int prefformat
Only alaw and mulaw is allowed for now.
static char * handle_cli_misdn_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int reason
enum AST_REDIRECTING_REASON value for redirection
static void update_name(struct ast_channel *tmp, int port, int c)
Redirecting information struct.
struct misdn_bchannel * bc
Associated B channel structure.
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
#define chan_list_unref(obj, debug)
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define AST_CAUSE_CALL_REJECTED
int misdn_cfg_is_port_valid(int port)
Asterisk module definitions.
union misdn_bchannel::@126 AOCD
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
struct misdn_jb * misdn_jb_init(int size, int upper_threshold)
allocates the jb-structure and initialize the elements
static int misdn_to_ast_screen(int screening)
int law
Companding ALaw/uLaw encoding (INFO_CODEC_ALAW / INFO_CODEC_ULAW)
int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the...
static snd_pcm_format_t format
union ast_frame::@172 data
struct ast_channel_tech * tech
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
int orig
Who originated the call (ORG_AST, ORG_MISDN)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
struct FacParm fac_in
Inbound FACILITY message function type and contents.
static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
static char * handle_cli_misdn_show_stacks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
unsigned char valid
TRUE if the number information is valid/present.
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
#define ast_custom_function_register(acf)
Register a custom function.
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
static ast_mutex_t cl_te_lock
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
struct FacAOCDChargingUnit chargingUnit
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
char exten[AST_MAX_EXTENSION]
const char * ast_pickup_ext(void)
Determine system call pickup extension.
Structure for mutex and tracking information.
int count
Number of times the call has been redirected.
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
int l3_id
Layer 3 process ID.
static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
static char * handle_cli_misdn_show_ports_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static void misdn_queue_connected_line_update(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
static char * handle_cli_misdn_port_up(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static enum event_response_e cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
#define ast_mutex_unlock(a)
void(* cb_log)(int level, int port, char *tmpl,...)
int early_bconnect
TRUE if the call progress indicators can indicate an inband audio message for the user to listen to...
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
struct ast_party_number number
Subscriber phone number.
int toggle_ec
TRUE if echo canceller is enabled. Value is toggled.