⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgc_user.c

📁 一个Megaco实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
// ``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 + -