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

📄 mgc_user.c

📁 一个Megaco实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
extern void mgc_user_terminate(CORBA_Environment* s_env,			       CORBA_Environment* r_env) {  VERBOSE( ("mgc user terminate\n") );}/************************************************************ * Setup Transport ************************************************************/static void setup_transport() {  Megaco_ReceiveHandle      rh;  MegacoSessionIp_IpOption  port;  MegacoSessionIp_IpOptions ipOptions;  V( ("setup transport\n") );  rh.localMid = mid;  /* Setup text port for both UDP and TCP */  port._d      = MegacoSessionIp_Ip_port;  port._u.port = 2944;  ipOptions._buffer  = &port;  ipOptions._length  = 1;  ipOptions._maximum = 1;  prepare_udp(&dummy);  /* prepare receive handle for udp text */  rh.encodingMod    = "megaco_pretty_text_encoder";  rh.encodingConfig = "";    rh.sendMod        = "megaco_udp";  V( ("open UDP text (port 2944) connection\n") );  MegacoSessionUdp_open(NULL,			ref_counter,			&session_user_pid,			&rh,			&ipOptions,			send_env);  ASSERT_SEND();  prepare_tcp(&dummy);  /* prepare receive handle for tcp text */  rh.sendMod        = "megaco_tcp";  V( ("open TCP text (port 2944) connection\n") );  MegacoSessionTcp_listen(NULL,			  ref_counter,			  &session_user_pid,			  &rh,			  &ipOptions,			  send_env);  ASSERT_SEND();  /* Setup binary port for both UDP and TCP */  port._u.port = 2945;  prepare_udp(&dummy);  rh.encodingMod    = "megaco_binary_encoder";  rh.encodingConfig = "";    rh.sendMod        = "megaco_udp";  V( ("open UDP binary (port 2945) connection\n") );  MegacoSessionUdp_open(NULL,			ref_counter,			&session_user_pid,			&rh,			&ipOptions,			send_env);  ASSERT_SEND();  prepare_tcp(&dummy);  /* prepare receive handle for tcp binary */  rh.sendMod        = "megaco_tcp";  V( ("open TCP binary (port 2945) connection\n") );  MegacoSessionTcp_listen(NULL,			ref_counter,			&session_user_pid,			&rh,			&ipOptions,			send_env);  ASSERT_SEND();  V( ("requests sent - now await response\n") );}/************************************************************ * Session User Callback Functions ************************************************************/Megaco_SessionUser_startSessionResponse__rs* Megaco_SessionUser_startSessionResponse__cb(Megaco_SessionUser oe_obj, 					    CORBA_long *ref, 					    Megaco_Status *status, 					    erlang_pid *pid,  					    CORBA_Environment *oe_env) {  Megaco_UserInfoValues uiv;  V( ("received startSessionResponse\n") );  ASSERT_OK(status);  /* Now we have got the id of the session process, */  session_pid.num      = pid->num;  session_pid.serial   = pid->serial;  session_pid.creation = pid->creation;  strcpy(session_pid.node, pid->node);  /* Create the user info values    * The following values should be set:   * reply_timer & resend_timer   */  uiv._maximum = 0;  uiv._length  = 0;  uiv._buffer  = NULL;  prepare_session(&dummy, pid);  V( ("send startUser\n") );  Megaco_Session_startUser(NULL, *ref, &session_user_pid, 			   &mid, &uiv, send_env);  ASSERT_SEND();  free((void*)status);  return (Megaco_SessionUser_startSessionResponse__rs*)NULL;}Megaco_SessionUser_sessionsResponse__rs* Megaco_SessionUser_sessionsResponse__cb(Megaco_SessionUser oe_obj, 					CORBA_long *ref, 					Megaco_Status *status, 					Megaco_SessionRefList *reflist, 					CORBA_Environment *oe_env) {  VERBOSE( ("received sessionResponse\n") );  free((void*)status);  free((void*)reflist);  return (Megaco_SessionUser_sessionsResponse__rs*)NULL;}Megaco_SessionUser_stopSessionResponse__rs* Megaco_SessionUser_stopSessionResponse__cb(Megaco_SessionUser oe_obj, 					   CORBA_long *ref, 					   Megaco_Status *status, 					   CORBA_Environment *oe_env) {    VERBOSE( ("received stopSessionResponse\n") );  free((void*)status);  return (Megaco_SessionUser_stopSessionResponse__rs*)NULL;}Megaco_SessionUser_handleConnect__rs* Megaco_SessionUser_handleConnect__cb(Megaco_SessionUser    oe_obj, 				     CORBA_long*           ref, 				     erlang_pid*           pid, 				     Megaco_ConnHandle*    handle, 				     CORBA_unsigned_short* XXX, 				     CORBA_Environment*    oe_env) {  Megaco_Status result;  int           res;  V( ("received handleConnect\n") );  /*    * We should perhaps do some checking here, to see if this   * is an accepted MG, but since this is a simple example   * we assume that it is ok.   */  print_pid("pid:       ", pid);  print_mid("localMid:  ", &handle->localMid);  print_mid("remoteMid: ", &handle->remoteMid);  switch ((res = mg_connect(&handle->remoteMid))) {  case MG_OK:  case MG_CONNECTED:    /* With UDP the MG can go and come without us knowing it, unless we     * implement some sort of polling mechanism (which we don't in this     * wery simple example), such as audit on the root termination.      * We just assume this is OK, and start the MG starting sequence...     */    V( ("connected (%d)\n", res) );    result._d = Megaco_ok;    break;  default:    VERBOSE( ("connect failed: %dn", res) );    result._d                  = Megaco_errorDesc;    result._u.desc.code        = MEGACO_INSUFFICIENT_RESOURCES;        result._u.desc.text._d     = TRUE;    result._u.desc.text._u.val = "Cannot allocate more than " MAX_MG_STRING;  }  prepare_session(&dummy, pid);    V( ("send handleConnectResponse\n") );  Megaco_Session_handleConnectResponse(NULL, *ref, &result, send_env);  free((void*)handle);  return (Megaco_SessionUser_handleConnect__rs*)NULL;}Megaco_SessionUser_handleDisconnect__rs* Megaco_SessionUser_handleDisconnect__cb(Megaco_SessionUser oe_obj, 					CORBA_long *ref, 					erlang_pid *pid, 					Megaco_ConnHandle *handle, 					CORBA_unsigned_short *XXX, 					CORBA_char *XXX2, 					CORBA_Environment *oe_env) {  int res;  V( ("received handleDisconnect\n") );  print_pid("pid:       ", pid);  print_mid("localMid:  ", &handle->localMid);  print_mid("remoteMid: ", &handle->remoteMid);    if ((res = mg_disconnect(&handle->remoteMid)) != MG_OK) {    VERBOSE( ("disconnect error %d from MG\n", res) );  }  free((void*)handle);  free((void*)XXX2);  return (Megaco_SessionUser_handleDisconnect__rs*)NULL;}Megaco_SessionUser_handleSyntaxError__rs* Megaco_SessionUser_handleSyntaxError__cb(Megaco_SessionUser oe_obj, 					 CORBA_long *ref, 					 erlang_pid *pid, 					 Megaco_ReceiveHandle *handle, 					 CORBA_unsigned_short *XXX, 					 MegacoMessage_ErrorDescriptor *error, 					 CORBA_Environment *oe_env) {    VERBOSE( ("received handleSyntaxError\n") );  print_pid("pid:       ", pid);  print_error_desc("syntax error: ", error);  free((void*)handle);  free((void*)error);  return (Megaco_SessionUser_handleSyntaxError__rs*)NULL;}Megaco_SessionUser_handleMessageError__rs* Megaco_SessionUser_handleMessageError__cb(Megaco_SessionUser oe_obj, 					  CORBA_long *ref,					  erlang_pid *pid, 					  Megaco_ConnHandle *handle, 					  CORBA_unsigned_short *XXX, 					  MegacoMessage_ErrorDescriptor *error, 					  CORBA_Environment *oe_env) {      VERBOSE( ("received handleMessageError\n") );  print_pid("pid:       ", pid);  print_mid("localMid:  ", &handle->localMid);  print_mid("remoteMid: ", &handle->remoteMid);  print_error_desc("message error: ", error);  free((void*)handle);  free((void*)error);  return (Megaco_SessionUser_handleMessageError__rs*)NULL;}Megaco_SessionUser_handleTransRequest__rs* Megaco_SessionUser_handleTransRequest__cb(Megaco_SessionUser oe_obj, 					  CORBA_long *ref, 					  erlang_pid *pid, 					  Megaco_ConnHandle *handle, 					  CORBA_unsigned_short *XXX, 					  Megaco_ActionRequests *action, 					  CORBA_Environment *oe_env) {  Megaco_Status         result;  Megaco_ActionReplies  actReplies;  MgInfo*               mgP;  int                   res;    V( ("received handleTransRequest\n") );    print_pid("pid:       ", pid);  print_mid("localMid:  ", &handle->localMid);  print_mid("remoteMid: ", &handle->remoteMid);    switch ((res = mg_lookup(&handle->remoteMid, &mgP))) {  case MG_OK:    V( ("handle transaction\n") );    result._d = Megaco_ok;    handle_transaction_requests(mgP, action, &result, &actReplies);    break;  default:    V( ("lookup failed: %d\n", res) );    result._d                  = Megaco_errorDesc;    result._u.desc.code        = MEGACO_INTERNAL_GATEWAY_ERROR;        result._u.desc.text._d     = TRUE;    result._u.desc.text._u.val = "MG not yet connected";    actReplies._maximum = 0;    actReplies._length  = 0;    actReplies._buffer  = NULL;    break;  }  prepare_session(&dummy, pid);    V( ("send handleTransRequestResponse\n") );  Megaco_Session_handleTransRequestResponse(NULL, *ref, &result, FALSE, 					    &actReplies, send_env);  free_action_replies(&actReplies);  free((void*)handle);  free((void*)action);  return (Megaco_SessionUser_handleTransRequest__rs*)NULL;}/* AAAARRRG, UGLY */static void free_action_replies(Megaco_ActionReplies* actRepliesP) {  int i;  for( i = 0 ; i < actRepliesP->_length ; i++) {    free(actRepliesP->_buffer[i].commandReply._buffer);  }  free(actRepliesP->_buffer);}static void handle_transaction_requests(MgInfo*                mgP,					Megaco_ActionRequests *actRequestsP,					Megaco_Status*         statusP,					Megaco_ActionReplies*  actRepliesP) {  int i;  V( ("trans request for Mg '%s' in state %d\n", mgP->mid, mgP->state) );  statusP->_d = Megaco_ok;  actRepliesP->_maximum = actRequestsP->_maximum;  actRepliesP->_length  = actRequestsP->_length;  if (actRepliesP->_length == 0) {    actRepliesP->_buffer = NULL;    return;  }     actRepliesP->_buffer =     malloc((actRepliesP->_length) * sizeof(MegacoMessage_ActionReply));  if (actRepliesP->_buffer == NULL) {    V( ("(act) memory alloc failed\n") );    mgc_exit(send_env, receive_env);  }      /*    * The proper way to do this would of course be to send a reply for   * each action request. But since this is a simple example we abort   * as soon as status is not ok.   */  for (i = 0 ; (i < actRepliesP->_length) && (statusP->_d == Megaco_ok)  ; i++) {    handle_transaction_request(mgP, &actRequestsP->_buffer[i],			       statusP, &actRepliesP->_buffer[i]);  }  /*    * If result is not Megaco_ok, then we send an "empty" ActionReply    */  if (statusP->_d != Megaco_ok) {    V( ("(act) abort transaction\n") );    actRepliesP->_maximum = 0;    actRepliesP->_length  = 0;    free(actRepliesP->_buffer);  }}static void handle_transaction_request(MgInfo*                      mgP,				       MegacoMessage_ActionRequest* actRequestP,				       Megaco_Status*               statusP,				       MegacoMessage_ActionReply*   actReplyP) {  MegacoMessage_ActionRequest_commandRequests* cmdReqP = &actRequestP->commandRequests;  MegacoMessage_ActionReply_commandReply*      cmdRepP = &actReplyP->commandReply;  V( ("context id: %d\n", (int) actRequestP->id) );  actReplyP->id                  = actRequestP->id;    // If any command goes wrong we abort everything (simple...)  actReplyP->errorDescriptor._d  = FALSE;  actReplyP->contextReply._d     = FALSE;  cmdRepP->_maximum = cmdReqP->_maximum;  cmdRepP->_length  = cmdReqP->_length;  if (cmdRepP->_length == 0) {    V( ("no command requests found\n") );    cmdRepP->_buffer = NULL;    return;  }   cmdRepP->_buffer = malloc((cmdRepP->_length) * sizeof(MegacoMessage_ActionReply));  if (cmdRepP->_buffer == NULL) {    V( ("(cmd) memory alloc failed\n") );    mgc_exit(send_env, receive_env);  }  /*    * The proper way to do this would of course be to send a reply for   * each command request. But since this is a simple example we abort    * as soon as status is not ok.   */  {    int i;    for(i = 0 ; (i < cmdRepP->_length) && (statusP->_d == Megaco_ok) ; i++) {      handle_command_request(mgP, actRequestP->id, 			     &cmdReqP->_buffer[i], &cmdRepP->_buffer[i], statusP);    }  }  /* If result is not Megaco_ok, then we send an "empty" command reply */  if (statusP->_d != Megaco_ok) {    V( ("(cmd) abort transaction\n") );    cmdRepP->_maximum = 0;    cmdRepP->_length  = 0;    free(cmdRepP->_buffer);  }}static void handle_command_request(MgInfo*                          mgP,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -