mgc.c
来自「一个Megaco实现源代码」· C语言 代码 · 共 576 行 · 第 1/2 页
C
576 行
exit(-1); } } /* check arguments */ if (strlen(host) == 0) { if ((gethostname(host,HOSTNAMESZ))) { fprintf(stderr,"can't find own hostname\n"); exit(-1); } } if (strlen(fhost) == 0) { strcpy(fhost,host); } sprintf(fnode, "%s@%s", fname, fhost); V( ("settings: \n" " name: %s\n" " device name: %s\n" " factory host: %s\n" " factory node name: %s\n", uname, dname, fhost, fname) );}static void usage() { fprintf(stderr, "usage: mgc [-cookie <cookie> -name <name> -fname <fname> -fhost <fhost> -h -v]\n\n" " -h Prints this information\n" " -v Verbose mode\n" " -cookie <cookie> Sets the magic cookie of this node to <cookie>\n" " Default is retrieved from cookie file\n" " -dname <name> Device name (mid) of the mgc. Default is '" DNAME_DEFAULT "'.\n" " -sname <name> Name of this session user node. Default is '" UNAME_DEFAULT "'.\n" " This will be used to form the MGC deviceName\n" " gateway_<uname>. Defaults to: 'gateway_" UNAME_DEFAULT "'\n" " -name <name> Fully quallified name of this session user " "c-node.\n" " The structure of this is <name>@<host>. \n" " Example: " UNAME_DEFAULT "@hobbes.ericsson.se \n" " The <name> part will be used to form the MGC \n" " deviceName gateway_<name>. \n" " -fname <fname> Name of the session factory node (as given by -sname). \n" " Default is '" FNAME_DEFAULT "'\n" " -fhost <fhost> Host of the session factory node. \n" " Default is localhost\n\n");}/* Server Loop * This should be utilized in a concurrent manner as three or more threads: * - one thread that only receives Erlang messages and * copies them into an incoming mailbox queue. If the * message is a synchronous gen_server call, the sending * pid and the unique message refreence also needs to be * copied. * - a pool of worker threads that picks messages from * the incoming mailbox, handles them and possibly * puts them into an outbound mailbox. * - one thread that only picks messages from the * outbound queue and sends Erlang messages. */ static void mgc_main(CORBA_Environment *s_env, CORBA_Environment *r_env, int sd, int epmd_fd) { ___map___* map; erlang_msg msg; int status = 1; /* Initiate the call table */ map = InitSwitch(); while (status >= 0) { /* write message to buffer */ V( ("await message\n") ); status = ei_receive_encoded(s_env->_fd, &s_env->_inbuf, &s_env->_inbufsz, &msg, &s_env->_iin); V( ("receive status: %d\n", status) ); switch(status) { case ERL_SEND: case ERL_REG_SEND : /* Switch incoming */ ___switch___(r_env, s_env, map); switch(s_env->_major) { case CORBA_NO_EXCEPTION: /* Success */ break; case CORBA_SYSTEM_EXCEPTION: /* System exception */ printf("Request failure, reason : %s\n", (char *) CORBA_exception_value(s_env)); CORBA_exception_free(s_env); break; default: /* Should not come here */ CORBA_exception_free(s_env); break; } /* send outdata */ if (s_env->_iout > 0) { V( ("send data: %d\n", s_env->_iout) ); ei_send_encoded(s_env->_fd, &s_env->_caller, s_env->_outbuf, s_env->_iout); } break; case ERL_TICK : V( ("received tick\n") ); break; default : /* < 0 */ printf("Connection terminated\n"); break; } }} /* Stopping node */extern void mgc_exit(CORBA_Environment *s_env, CORBA_Environment *r_env) { /* Close connection */ V( ("exiting -> close erl connection\n") ); erl_close_connection(s_env->_fd); /* Close file descriptors */ eterminate(&s_env->_fd, &sd, &epmd_fd); /* Free env & buffers */ V( ("exiting -> free environment and buffers\n") ); CORBA_free(r_env->_inbuf); CORBA_free(r_env->_outbuf); CORBA_free(r_env); CORBA_free(s_env->_inbuf); CORBA_free(s_env->_outbuf); CORBA_free(s_env); exit(1);}static ___map___* InitSwitch() { ___map___ marray[3] = { ___Megaco_SessionUser_map___, ___MegacoSessionTcpUser_map___, ___MegacoSessionUdpUser_map___ }; return ___merge___(marray,3);}static int einit(int *sd, int *portnr, int *epmd_fd) { struct hostent *h; /* identify host */ V( ("initiating -> identify host\n") ); if (!(h = erl_gethostbyname(host))) fprintf(stdout,"can't find own ip address\n"); else { /* get a listen port. 0 means let system choose port number */ V( ("initiating -> get listen port: ") ); *sd = getlisten(0); /* what port did we get? */ /* this call not necessary if we specified port in call to getlisten() */ *portnr = getport(*sd); V( ("%d\n", *portnr) ); /* make our nodename server@host */ sprintf(unode,"%s@%s", uname, host); /* initiate */ V( ("initiating -> erl initiate\n") ); erl_init(NULL,0); /* host, alive, alive@host, addr, cookie, creation */ V( ("initiating -> erl connect\n") ); erl_connect_xinit(host, uname, unode,(Erl_IpAddr)(h->h_addr_list[0]),cookie,0); /* let epmd know we are here */ V( ("initiating -> erl publish (let EPMD know we are here)\n") ); *epmd_fd = erl_publish(*portnr); /* Create and init CORBA_Environments */ V( ("initiating -> create CORBA environment\n") ); send_env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); /* env for local side */ receive_env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); /* env for remote side */ /* Connect to other side */ fprintf(stderr, "Connecting to '%s' ... ", fnode); send_env->_fd = erl_connect(fnode); if (send_env->_fd < 0) { /* error */ fprintf(stderr,"\nERROR: Connection failed: %s\n", strerror(errno)); mgc_exit(send_env, receive_env); } fprintf(stderr, "done\n"); receive_env->_fd = send_env->_fd; return 0; } return -1;}static void eterminate(int *fd, int *sd, int *epmd_fd) { close(*fd); /* remove info from epmd */ close(*epmd_fd); /* return socket */ close(*sd);}/* tells you what port you are using on given socket */static int getport(int sockd) { struct sockaddr_in addr; int namelen = sizeof(addr); int i; memset(&addr,0,sizeof(addr)); if ((i = getsockname(sockd,(struct sockaddr *)&addr,&namelen))<0) return i; return ntohs(addr.sin_port);}/* return a listen socket, bound to given port *//* specify port = 0 to let system assign port */static int getlisten(int port) { int sockd; struct sockaddr_in inaddr; int opt = 1; int i; /* get listen socket */ if ((sockd = socket(AF_INET,SOCK_STREAM,0)) < 0) return sockd; if ((i=setsockopt(sockd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)))<0) return i; /* bind to requested port */ memset(&inaddr,0,sizeof(inaddr)); inaddr.sin_family = AF_INET; inaddr.sin_addr.s_addr = htonl(INADDR_ANY); inaddr.sin_port = htons(port); if ((i = bind(sockd,(struct sockaddr*) &inaddr, sizeof(inaddr))) < 0) return i; listen(sockd,5); return sockd;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?