hellopics-ctrl_conn.c

Go to the documentation of this file.
00001 /*
00002  * $Id: hellopics-ctrl_conn.c 346460 2009-11-14 05:06:47Z ssiano $
00003  *
00004  * This code is provided as is by Juniper Networks SDK Developer Support.
00005  * It is provided with no warranties or guarantees, and Juniper Networks
00006  * will not provide support or maintenance of this code in any fashion.
00007  * The code is provided only to help a developer better understand how
00008  * the SDK can be used.
00009  *
00010  * Copyright (c) 2007-2008, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00022 #include <string.h>
00023 #include <jnx/aux_types.h>
00024 #include <jnx/trace.h>
00025 #include <netinet/in.h>
00026 #include <arpa/inet.h>
00027 #include <jnx/pconn.h>
00028 #include <sync/hellopics_ipc.h>
00029 #include "hellopics-ctrl_conn.h"
00030 #include "hellopics-ctrl_logging.h"
00031 
00032 
00033 /*** Constants ***/
00034 #define RETRY_CONNECT_INTERVAL 200
00035 #define MGMT_CLIENT_CONNECT_RETRIES    3  
00036 #define HELLOPICS_CTRL_SERVER_MAX_CONN 1  
00037 
00038 
00039 /*** Data Structures ***/
00040 
00041 static pconn_server_t     * ctrl_server;     
00042 static pconn_session_t    * data_session;    
00043 static pconn_client_t     * mgmt_client;     
00044 static boolean            mgmt_connected;    
00045 static boolean            data_ready;        
00046 static evTimerID  ctrl_timer_id;     
00047 static evContext  ev_ctx;          
00048 
00049 
00050 /*** STATIC/INTERNAL Functions ***/
00051 
00052 static void
00053 connect_ctrl_pic(evContext ctx,
00054             void * uap  __unused,
00055             struct timespec due __unused,
00056             struct timespec inter __unused);
00069 static void
00070 client_connection(pconn_client_t * session,
00071                   pconn_event_t event,
00072                   void * cookie __unused)
00073 {
00074     int rc;
00075     uint32_t id;
00076 
00077     INSIST_ERR(session == mgmt_client); // there is only one client connection
00078 
00079     switch (event) {
00080 
00081         case PCONN_EVENT_ESTABLISHED:
00082         // clear the retry timer
00083         if(evTestID(ctrl_timer_id)) {
00084             evClearTimer(ev_ctx, ctrl_timer_id);
00085             evInitID(&ctrl_timer_id);
00086         }
00087         LOG(LOG_INFO, "%s: Connected to the management component",
00088                 __func__);
00089         
00090         id = htonl(HELLOPICS_ID_CTRL);
00091         rc = pconn_client_send(mgmt_client, MSG_ID, &id, sizeof(id));
00092                           
00093         if(rc != PCONN_OK) {
00094             LOG(LOG_ERR, "%s: Failed to send MSG_ID to the mgmt component. "
00095                     "Error: %d", __func__, rc);
00096             break;
00097         }
00098             
00099         mgmt_connected = TRUE;
00100 
00101         // Send ready if data component is already ready too 
00102         if(data_ready) {
00103             rc = pconn_client_send(mgmt_client, MSG_READY, NULL, 0);
00104             if(rc != PCONN_OK) {
00105                LOG(LOG_ERR, "%s: Failed to send MSG_READY to the mgmt "
00106                    "component. Error: %d", __func__, rc);
00107             }
00108         }
00109         break;
00110 
00111         case PCONN_EVENT_SHUTDOWN:
00112         if(mgmt_client != NULL) {
00113             LOG(LOG_INFO, "%s: Disconnected from the hellopics-mgmt component"
00114                     " on the RE", __func__);
00115         }
00116         mgmt_client = NULL;
00117         // Reconnect to it if timer not going
00118         if(!evTestID(ctrl_timer_id) &&
00119            evSetTimer(ev_ctx, connect_ctrl_pic, NULL, evConsTime(0,0),
00120                evConsTime(RETRY_CONNECT_INTERVAL, 0), &ctrl_timer_id)) {
00121 
00122             LOG(LOG_EMERG, "%s: Failed to initialize a re-connect timer to "
00123                 "reconnect to the mgmt component", __func__);
00124         }
00125             break;
00126     case PCONN_EVENT_FAILED:
00127 
00128         LOG(LOG_ERR, "%s: Received a PCONN_EVENT_FAILED event", __func__);
00129         if(mgmt_client != NULL) {
00130             LOG(LOG_INFO, "%s: Disconnected from the hellopics-mgmt component"
00131                     " on the RE", __func__);
00132         }
00133         mgmt_client = NULL; // connection will be closed
00134         // Reconnect to it if timer not going
00135         if(!evTestID(ctrl_timer_id) &&
00136            evSetTimer(ev_ctx, connect_ctrl_pic, NULL, evConsTime(0,0),
00137                evConsTime(RETRY_CONNECT_INTERVAL, 0), &ctrl_timer_id)) {
00138             LOG(LOG_EMERG, "%s: Failed to initialize a re-connect timer to "
00139                 "reconnect to the mgmt component", __func__);
00140         }
00141         
00142         default:
00143             LOG(LOG_ERR, "%s: Received an unknown or PCONN_EVENT_FAILED event",
00144                  __func__);
00145             break;
00146     }
00147 }
00148 
00149 
00165 static status_t
00166 client_message(pconn_client_t * session,
00167                ipc_msg_t * msg,
00168                void * cookie __unused)
00169 {
00170     int rc;
00171     
00172     INSIST_ERR(session == mgmt_client); // there is only one client connection
00173     INSIST_ERR(msg != NULL);
00174 
00175     switch(msg->subtype) {
00176         
00177         case MSG_HELLO:
00178             // Received a HELLO from the mgmt component, so
00179             // pass it along to the data component
00180             
00181             INSIST_ERR(msg->length == sizeof(uint32_t));
00182             LOG(LOG_INFO, "%s: Forwarding HELLO packet from mgmt to data",
00183                 __func__);
00184             rc = pconn_server_send(data_session, MSG_HELLO,
00185                                    msg->data, sizeof(uint32_t));
00186             if(rc != PCONN_OK) {
00187                 LOG(LOG_ERR, "%s: Failed to send HELLO to data component. "
00188                     "Error: %d", __func__, rc);
00189             }
00190             break;
00191         
00192         default:
00193         
00194             LOG(LOG_ERR, "%s: Received an unknown message type (%d) from the "
00195                 "management component", __func__, msg->subtype);
00196             break;
00197     }
00198 
00199     
00200     return SUCCESS;
00201 }
00202 
00203 
00216 static void
00217 receive_connection(pconn_session_t * session,
00218                    pconn_event_t event,
00219                    void * cookie __unused)
00220 {
00221     pconn_peer_info_t info;
00222     int rc;
00223     
00224     rc = pconn_session_get_peer_info(session, &info);
00225     
00226     if(rc != PCONN_OK) {
00227         LOG(LOG_ERR, "%s: Cannot retrieve peer info for session. Error: %d",
00228              __func__, rc);
00229          return;
00230     } else {
00231         INSIST_ERR(info.ppi_peer_type == PCONN_PEER_TYPE_PIC);
00232     }
00233 
00234     switch (event) {
00235 
00236         case PCONN_EVENT_ESTABLISHED:
00237             data_session = session;
00238             break;
00239 
00240         case PCONN_EVENT_SHUTDOWN:
00241             
00242             if(session == data_session) {
00243                 data_session = NULL;
00244                 
00245                 LOG(LOG_INFO, "%s: Connection from the data component shutdown",
00246                     __func__);
00247                 
00248             } else {
00249                 LOG(LOG_ERR, "%s: Cannot find an existing peer session "
00250                     "to shutdown", __func__);
00251             }
00252                       
00253             break;
00254 
00255         default:
00256             LOG(LOG_ERR, "%s: Received an unknown or PCONN_EVENT_FAILED event",
00257                  __func__);
00258             break;
00259     }
00260 }
00261 
00262 
00279 static status_t
00280 receive_message(pconn_session_t * session,
00281                 ipc_msg_t * msg,
00282                 void * cookie __unused)
00283 {
00284     int rc;
00285     uint32_t id;
00286     
00287     INSIST_ERR(session == data_session);
00288 
00289     switch(msg->subtype) {
00290         
00291         case MSG_READY:
00292 
00293             data_ready = TRUE;
00294             
00295             // Send ready if mgmt component is connected 
00296             if(mgmt_connected) {
00297                 rc = pconn_client_send(mgmt_client, MSG_READY, NULL, 0);
00298                 if(rc != PCONN_OK) {
00299                     LOG(LOG_ERR, "%s: Failed to send MSG_READY to mgmt "
00300                         "component. Error %d", __func__, rc);
00301                 }
00302             }
00303 
00304             break;
00305             
00306         case MSG_HELLO:
00307             
00308             // Received a HELLO from the data component, so
00309             // pass it along to the mgmt component
00310             
00311             INSIST_ERR(msg->length == sizeof(uint32_t));
00312             LOG(LOG_INFO, "%s: Forwarding HELLO packet from data to mgmt",
00313                 __func__);
00314             rc = pconn_client_send(mgmt_client, MSG_HELLO,
00315                                    msg->data, sizeof(uint32_t));
00316             if(rc != PCONN_OK) {
00317                 LOG(LOG_ERR, "%s: Failed to send HELLO to mgmt component. "
00318                     "Error: %d", __func__, rc);
00319             }
00320 
00321             break;
00322         
00323         case MSG_ID:
00324         
00325             INSIST_ERR(msg->length == sizeof(uint32_t));
00326         
00327             id = ntohl(*((uint32_t *)msg->data));
00328             if(id != HELLOPICS_ID_DATA) {
00329                 LOG(LOG_ERR, "%s: Received an ID (%d) that is not the "
00330                     "data component", __func__, id);
00331                 break;
00332             }
00333             LOG(LOG_INFO, "%s: Received a connection from the data component",
00334                 __func__);
00335         
00336             break;
00337         
00338         default:
00339         
00340             LOG(LOG_ERR, "%s: Received an unknown message type (%d) from the "
00341                 "data component", __func__, msg->subtype);
00342             break;
00343     }
00344      
00345     return SUCCESS;
00346 }
00347 
00348 /*** GLOBAL/EXTERNAL Functions ***/
00349 
00350 
00358 static void
00359 connect_ctrl_pic(evContext ctx,
00360             void * uap  __unused,
00361             struct timespec due __unused,
00362             struct timespec inter __unused)
00363 {
00364     pconn_server_params_t s_params;
00365     pconn_client_params_t c_params;
00366     
00367     // init the sessions
00368     data_session = NULL;
00369     
00370     // init the client in case it doesn't get init'd below
00371     mgmt_client = NULL;
00372     
00373     // init module's other variables
00374     data_ready = FALSE;
00375     mgmt_connected = FALSE;
00376 
00377     bzero(&s_params, sizeof(pconn_server_params_t));
00378     
00379     // setup the server args
00380     s_params.pconn_port            = HELLOPICS_PORT_NUM;
00381     s_params.pconn_max_connections = HELLOPICS_CTRL_SERVER_MAX_CONN;
00382     s_params.pconn_event_handler   = receive_connection;
00383     
00384     // bind
00385     ctrl_server = pconn_server_create(&s_params, ctx, receive_message, NULL);
00386     
00387     if(ctrl_server == NULL) {
00388         LOG(LOG_ERR, "%s: Failed to initialize the pconn server on port %d.",
00389             __func__, HELLOPICS_PORT_NUM);
00390     }
00391     
00392 
00393     bzero(&c_params, sizeof(pconn_client_params_t));
00394     
00395     // setup the client args
00396     c_params.pconn_peer_info.ppi_peer_type = PCONN_PEER_TYPE_RE;
00397     c_params.pconn_port                    = HELLOPICS_PORT_NUM;
00398     c_params.pconn_num_retries             = MGMT_CLIENT_CONNECT_RETRIES;
00399     c_params.pconn_event_handler           = client_connection;
00400     
00401     // connect
00402     mgmt_client = pconn_client_connect_async(
00403                     &c_params, ctx, client_message, NULL);
00404     
00405     if(mgmt_client == NULL) {
00406         LOG(LOG_ERR, "%s: Failed to initialize the pconn client connection "
00407             "to the management component", __func__);
00408     }
00409 }
00419 status_t
00420 init_connections(evContext ctx)
00421 {
00422     mgmt_client = NULL;
00423     
00424     ev_ctx = ctx;
00425     
00426     evInitID(&ctrl_timer_id);
00427     
00428     // Connect to the MGMT component
00429     if(evSetTimer(ctx, connect_ctrl_pic, NULL, evNowTime(),
00430         evConsTime(RETRY_CONNECT_INTERVAL, 0), &ctrl_timer_id)) {
00431 
00432         LOG(LOG_EMERG, "%s: Failed to initialize a connect timer to connect "
00433             "to the MGMT component", __func__);
00434         return EFAIL;
00435     }
00436 
00437     return SUCCESS;
00438 }
00439 
00440 
00444 void
00445 close_connections(void)
00446 {
00447     if(data_session) {
00448         pconn_session_close(data_session);
00449         data_session = NULL;
00450     }
00451     
00452     if(ctrl_server) {
00453         pconn_server_shutdown(ctrl_server);
00454         ctrl_server = NULL;
00455     }
00456 
00457     if(mgmt_client) {
00458         pconn_client_close(mgmt_client);
00459         mgmt_client = NULL;
00460     }
00461 }

2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:26:58 2010 for SDK Your Net Corporation Hellopics Example: hellopics-ctrl 1.0 by Doxygen 1.5.1