📄 mgc_user.c
字号:
// ``The contents of this file are subject to the Erlang Public License,// Version 1.1, (the "License"); you may not use this file except in// compliance with the License. You should have received a copy of the// Erlang Public License along with this software. If not, it can be// retrieved via the world wide web at http://www.erlang.org/.//// Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See// the License for the specific language governing rights and limitations// under the License.//// The Initial Developer of the Original Code is Ericsson Utvecklings AB.// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings// AB. All Rights Reserved.''//// $Id$#include <stdlib.h>#include <string.h>#include "megaco_session.h"#include "mgc_user.h"#include "mgc.h"#include "verbose.h"// Megaco error codes#define MEGACO_INTERNAL_GATEWAY_ERROR 500#define MEGACO_NOT_IMPLEMENTED 501#define MEGACO_INSUFFICIENT_RESOURCES 510#define MG_OK 0 // Successfull allocation#define MG_CONNECTED 1 // Reused Successfull allocation#define MG_FULL 2 // Max MG's reached#define MG_UNSUPPORTED_MID_TYPE 3 // Only device mid allowed#define MG_UNKNOWN 4 // Could not find the requested MG#define FALSE 0#define TRUE 1#define MEGACO_SESSION_FACTORY "megaco_session_factory"#define MEGACO_SESSION_UDP "megaco_session_udp"#define MEGACO_SESSION_TCP "megaco_session_tcp"#define MAXPENDING 512#define MAX_MG 8#define MAX_MG_STRING "8" #define NAMESZ 128#define ASSERT_OK(status) assert_ok(status, __FILE__, __LINE__)#define ASSERT_SEND() assert_send(__FILE__, __LINE__)#define V( proto ) if (verbose) VERBOSE( proto )/* * For this simple example, we know that our MGs use only the device name, * and that it will _never_ be at most 64 char long... */typedef enum {MgsUndefined = 0, MgsConnected, MgsOperational} MgState;typedef struct { MgState state; char mid[64]; } MgInfo;static CORBA_Environment* send_env = NULL;static CORBA_Environment* receive_env = NULL;static erlang_pid session_pid;static erlang_pid session_user_pid;static char dname[NAMESZ];static Megaco_UserMid mid;static CORBA_long ref_counter = 0;static void* pending_messages[MAXPENDING];static char dummy[] = "dummy";static int verbose = FALSE;static MgInfo mg[MAX_MG];static void handle_transaction_requests(MgInfo* mgP, Megaco_ActionRequests *actRequestsP, Megaco_Status* statusP, Megaco_ActionReplies* actRepliesP);static void handle_transaction_request(MgInfo* mgP, MegacoMessage_ActionRequest* actRequestP, Megaco_Status* statusP, MegacoMessage_ActionReply* actReplyP);static void handle_command_request(MgInfo* mgP, int cid, MegacoMessage_CommandRequest* reqP, MegacoMessage_CommandReplyUnion* repP, Megaco_Status* statusP);static void handle_service_change_req(int cid, MegacoMessage_ServiceChangeRequest* reqP, MegacoMessage_ServiceChangeReply* repP, Megaco_Status* statusP);static void free_action_replies(Megaco_ActionReplies* actRepliesP);/************************************************************ * Helpers ************************************************************/static void assert_ok(Megaco_Status* status, char* file, int line) { switch(status->_d) { case Megaco_ok: break; case Megaco_errorString: fprintf(stderr, "%s(%i): errorString -> %s\n", file, line, status->_u.result); mgc_exit(send_env, receive_env); break; case Megaco_errorDesc: if (status->_u.desc.text._d) { fprintf(stderr, "%s(%i): errorDesc(%i) -> %s\n", file, line, status->_u.desc.code, status->_u.desc.text._u.val); mgc_exit(send_env, receive_env); } else { fprintf(stderr, "%s(%i): errorDesc(%i)\n", file, line, (status->_u.desc).code); mgc_exit(send_env, receive_env); } }}static void assert_send(char* file, int line) { switch(send_env->_major) { case CORBA_NO_EXCEPTION: /* Success */ break; case CORBA_SYSTEM_EXCEPTION: /* System exception */ fprintf(stderr, "%s(%i): <ERROR> startSession send failure - %s\n", file, line, (char *) CORBA_exception_value(send_env)); CORBA_exception_free(send_env); mgc_exit(send_env, receive_env); default: /* Should not come here */ fprintf(stderr, "%s(%i): <ERROR> unknown major value - %d\n", file, line, send_env->_major); mgc_exit(send_env, receive_env); }}static void print_error_desc(char* prefix, MegacoMessage_ErrorDescriptor* errorP) { fprintf(stdout, "%s: {%d,", prefix, errorP->code); if (errorP->text._d) fprintf(stdout, "%s}\n", errorP->text._u.val); else fprintf(stdout, "-}\n");}static void print_pid(char* prefix, erlang_pid* pidP) { fprintf(stdout, "%s[<%d.%d.%d>,%s]\n", prefix, pidP->creation, pidP->num, pidP->serial, pidP->node);}static void print_mid_ip4(MegacoMessage_IP4Address ip4) { int i; fprintf(stdout, "ip4 - ["); for (i = 0 ; i < ip4.address._length ; i++) { fprintf(stdout, "%2d", ip4.address._buffer[i]); if (i < (ip4.address._length - 1)) fprintf(stdout, "."); } fprintf(stdout, "]"); if (ip4.portNumber._d) fprintf(stdout, ":%d", ip4.portNumber._u.val);}static void print_mid_ip6(MegacoMessage_IP6Address ip6) { int i; fprintf(stdout, "ip6 - ["); for (i = 0 ; i < ip6.address._length ; i++) { fprintf(stdout, "%2d", ip6.address._buffer[i]); if (i < (ip6.address._length - 1)) fprintf(stdout, "."); } fprintf(stdout, "]"); if (ip6.portNumber._d) fprintf(stdout, ":%d", ip6.portNumber._u.val);}static void print_mid_domain(MegacoMessage_DomainName domain) { fprintf(stdout, "domain - %s", domain.name); if (domain.portNumber._d) fprintf(stdout, ":%d", domain.portNumber._u.val);}static void print_mid_device(char* device) { fprintf(stdout, "device - %s", device);}static void print_mid_mtp(MegacoMessage_OctetString mtp) { int i; fprintf(stdout, "mtp - "); for (i = 0 ; i < mtp._length ; i++) { fprintf(stdout, "%d", mtp._buffer[i]); if (i < (mtp._length - 1)) fprintf(stdout, "."); }}static void print_mid(char* prefix, MegacoMessage_MIdUnion* midP) { fprintf(stdout, "%s", prefix); switch (midP->_d) { case MegacoMessage_MIdChoice_ip4Address: print_mid_ip4(midP->_u.ip4); break; case MegacoMessage_MIdChoice_ip6Address: print_mid_ip6(midP->_u.ip6); break; case MegacoMessage_MIdChoice_domainName: print_mid_domain(midP->_u.domain); break; case MegacoMessage_MIdChoice_deviceName: print_mid_device(midP->_u.device); break; case MegacoMessage_MIdChoice_mtpAddress: print_mid_mtp(midP->_u.mtp); break; case MegacoMessage_MIdChoice_preliminary: fprintf(stdout, "preliminary"); break; default: fprintf(stdout, "UNDEFINED(%d)", midP->_d); break; } fprintf(stdout, "\n"); fflush(stdout);}static int mg_connect(MegacoMessage_MIdUnion* midP) { int i; int foundMg = -1; int firstUnused = -1; /* First check that it is a mid type we support, i.e. device */ if (midP->_d != MegacoMessage_MIdChoice_deviceName) return ( MG_UNSUPPORTED_MID_TYPE ); /* Look for a free slot and if the MG is already there */ for (i = 0 ; (i < MAX_MG) && (foundMg < 0) ; i ++) { if (mg[i].state == MgsUndefined) { if (firstUnused < 0) firstUnused = i; } else { /* Found an used MG slot, check if it's the same */ if (strcmp(mg[i].mid, midP->_u.device) == 0) foundMg = i; } /* else */ } /* for (i = 0 ; (i < MAX_MG) && (found < 0) ; i ++) { */ if (foundMg >= 0) { mg[foundMg].state = MgsConnected; return ( MG_CONNECTED ); } else if (firstUnused >= 0) { mg[firstUnused].state = MgsConnected; strcpy(mg[firstUnused].mid, midP->_u.device); return ( MG_OK ); } else { return ( MG_FULL ); }}static int mg_disconnect(MegacoMessage_MIdUnion* midP) { int i; /* First check that it is a mid type we support, i.e. device */ if (midP->_d != MegacoMessage_MIdChoice_deviceName) return ( MG_UNSUPPORTED_MID_TYPE ); /* Look for the MG */ for (i = 0 ; i < MAX_MG ; i ++) { if (strcmp(mg[i].mid, midP->_u.device) == 0) { mg[i].state = MgsUndefined; mg[i].mid[0] = 0; return ( MG_OK ); } } /* for (i = 0 ; i < MAX_MG ; i ++) { */ return ( MG_UNKNOWN );}static int mg_lookup(MegacoMessage_MIdUnion* midP, MgInfo** mgP) { int i; int foundMg = -1; /* First check that it is a mid type we support, i.e. device */ if (midP->_d != MegacoMessage_MIdChoice_deviceName) return ( MG_UNSUPPORTED_MID_TYPE ); /* Look for a free slot and if the MG is already there */ for (i = 0 ; (i < MAX_MG) && (foundMg < 0) ; i ++) { if (mg[i].state != MgsUndefined) { /* Found an used MG slot, check if it's the same */ if (strcmp(mg[i].mid, midP->_u.device) == 0) foundMg = i; } /* if (mg[i].state != MgsUndefined) */ } /* for (i = 0 ; (i < MAX_MG) && (found < 0) ; i ++) { */ if (foundMg >= 0) { *mgP = &mg[foundMg]; return ( MG_OK ); } else { return ( MG_UNKNOWN ); }}static void insert_pending(void* state) { /* Find next free position in the pending_messages array * and store the state there. */ while(1) { ref_counter++; if (ref_counter >= MAXPENDING) { ref_counter = 0; } if (pending_messages[ref_counter] == NULL) { pending_messages[ref_counter] = state; break; } }}static void* delete_pending(CORBA_long ref) { void* state; if ((ref < MAXPENDING) && (0 <= ref)) { state = pending_messages[ref]; pending_messages[ref] = NULL; } else { state = NULL; fprintf(stderr, "message reference out of range: %d\n", (int) ref); mgc_exit(send_env, receive_env); } return state;}static void prepare_factory(void* state) { insert_pending(state); strcpy(send_env->_regname, MEGACO_SESSION_FACTORY); send_env->_to_pid = NULL; send_env->_from_pid = &session_user_pid;}static void prepare_udp(void* state) { insert_pending(state); strcpy(send_env->_regname, MEGACO_SESSION_UDP); send_env->_to_pid = NULL; send_env->_from_pid = &session_user_pid;}static void prepare_tcp(void* state) { insert_pending(state); strcpy(send_env->_regname, MEGACO_SESSION_TCP); send_env->_to_pid = NULL; send_env->_from_pid = &session_user_pid;}static void prepare_session(void* state, erlang_pid* to_pid) { insert_pending(state); send_env->_regname[0] = 0; send_env->_to_pid = to_pid; send_env->_from_pid = &session_user_pid;}/************************************************************ * Initiate Session User ************************************************************/extern void mgc_user_initiate(int v, char* device_name, char* local_node, CORBA_Environment* s_env, CORBA_Environment* r_env) { verbose = v; V( ("mgc user initiate\n") ); send_env = s_env; receive_env = r_env; session_user_pid.num = 99; session_user_pid.serial = 0; session_user_pid.creation = 0; strcpy(session_user_pid.node, local_node); strcpy(dname, device_name); mid._d = MegacoMessage_MIdChoice_deviceName; mid._u.device = dname; { int i; for (i = 0 ; i < MAX_MG ; i++) { mg[i].state = MgsUndefined; } } /* Send initial startSession message in order to get a valid session pid */ V( ("startSession\n") ); prepare_factory(&dummy); Megaco_SessionFactory_startSession(NULL, ref_counter, &session_user_pid, TRUE, send_env); ASSERT_SEND();}/************************************************************ * Terminate Session User ************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -