rw_status_t rwdts_appconf_register_keyspec_gi(rwdts_appconf_t *ac, const rw_keyspec_path_t *ks, uint32_t flags, rwdts_appconf_prepare_cb_gi prepare_cb, void *prepare_ud, GDestroyNotify prepare_cb_dtor, rwdts_member_reg_handle_t *handle_out) { rw_keyspec_path_t *remainder_ks = NULL; const rw_yang_pb_msgdesc_t *result = NULL; const rw_yang_pb_schema_t* schema = NULL; schema = ((ProtobufCMessage*)ks)->descriptor->ypbc_mdesc->module->schema; if (schema == NULL) { schema = rwdts_api_get_ypbc_schema(ac->apih); } if (!schema) { RWTRACE_CRIT(ac->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "register_xpath[%s] failed - Schema is NULL", "!!"); return (RW_STATUS_FAILURE); } rw_status_t rs = rw_keyspec_path_find_msg_desc_schema((rw_keyspec_path_t*)ks, NULL, schema, (const rw_yang_pb_msgdesc_t **)&result, &remainder_ks); if (rs != RW_STATUS_SUCCESS) { RWTRACE_CRIT(ac->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "rw_keyspec_path_find_msg_desc_schema failed for xapth[%s]", "!!"); return (rs); } if (remainder_ks != NULL) { char *remainder_ks_str; rw_keyspec_path_get_new_print_buffer(remainder_ks, NULL, schema, &remainder_ks_str); RWTRACE_CRIT(ac->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "Unknown keyspec in xapth[%s] - remainder_keyspec = [%s]", "!!", remainder_ks_str ? remainder_ks_str : ""); rw_keyspec_path_free(remainder_ks, NULL ); free(remainder_ks_str); remainder_ks = NULL; } rwdts_member_reg_handle_t han = rwdts_appconf_register_int(ac,ks,NULL,result->u->msg_msgdesc.pbc_mdesc,flags,(rwdts_appconf_prepare_cb_t)prepare_cb,prepare_ud,prepare_cb_dtor); *handle_out = han; if (han == NULL) { return RW_STATUS_FAILURE; } return RW_STATUS_SUCCESS; }
/** * Creates the pipes to communicate with the agent */ static int msg_channel_create(rwcli_msg_channel_t* ch) { int ret = pipe(ch->in.fds); if (ret != 0) { RWTRACE_CRIT(rwcli_controller.trace_ctxt, RWTRACE_CATEGORY_RWCLI, "Error creating IN pipe: %s", strerror(errno)); return -1; } ret = pipe(ch->out.fds); if (ret != 0) { RWTRACE_CRIT(rwcli_controller.trace_ctxt, RWTRACE_CATEGORY_RWCLI, "Error creating OUT pipe: %s", strerror(errno)); return -1; } return 0; }
void rwdts_appconf_prepare_complete_fail(rwdts_appconf_t *ac, const rwdts_xact_info_t *xact_info, rw_status_t rs, const char *errstr) { RW_ASSERT_TYPE(ac, rwdts_appconf_t); rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)xact_info->xact->group[ac->group->id]->scratch; RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t); RW_ASSERT(appx->queries_in > 0); appx->queries_out++; RW_ASSERT(appx->queries_out <= appx->queries_in); int idx = appx->errs_ct++; appx->errs = realloc(appx->errs, sizeof(appx->errs[0]) * appx->errs_ct); appx->errs[idx].str = strdup(errstr); appx->errs[idx].rs = rs; appx->errs[idx].corrid = (xact_info->queryh && ((RWDtsQuery*)xact_info->queryh)->has_corrid ? ((RWDtsQuery*)xact_info->queryh)->corrid : 0); rwdts_member_send_error(xact_info->xact, NULL, (RWDtsQuery*)xact_info->queryh, NULL, NULL, rs, errstr); RWTRACE_CRIT(xact_info->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "APPCONF prepare_complete_fail code %d str '%s'\n", rs, errstr); rwdts_xact_info_respond_keyspec(xact_info, RWDTS_XACT_RSP_CODE_NACK, NULL, NULL); }
void rwdts_appconf_xact_add_issue(rwdts_appconf_t *ac, rwdts_xact_t *xact, rw_status_t rs, const char *errstr) { RW_ASSERT_TYPE(ac, rwdts_appconf_t); if (xact) { RW_ASSERT_TYPE(xact, rwdts_xact_t); rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)xact->group[ac->group->id]->scratch; RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t); int idx = appx->errs_ct++; appx->errs = realloc(appx->errs, sizeof(appx->errs[0]) * appx->errs_ct); appx->errs[idx].str = strdup(errstr); appx->errs[idx].rs = rs; appx->errs[idx].corrid = 0; //?? // Send to error_report also rwdts_member_send_error(xact, NULL, NULL, ac->apih, NULL, rs, errstr); } else if (ac->group && ac->group->xact) { RW_ASSERT_TYPE(ac->group->xact, rwdts_xact_t); rwdts_member_send_error(ac->group->xact, NULL, NULL, ac->apih, NULL, rs, errstr); } else { if (ac->apih) { RWTRACE_CRIT(ac->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "%s: No xact, rs=%d, errstr=%s\n", __FUNCTION__, rs, errstr); } else { DTS_PRINT("%s: No xact, rs=%d, errstr=%s\n", __FUNCTION__, rs, errstr); } } if (ac->apih) { RWTRACE_ERROR(ac->apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "APPCONF xact issue for group %d, rs %d, errstr '%s'\n", ac->group->id, rs, errstr); } else { DTS_PRINT("APPCONF xact issue for group %d, rs %d, errstr '%s'\n", ac->group->id, rs, errstr); } }
/** * This method will be invoked whene the rw.cli executes a command and * requires a transport to send the message. */ static rw_status_t messaging_hook(NetconfReq *req, NetconfRsp **rsp) { // Send message to the CLI-AGENT and wait for a message back unsigned msg_len = netconf_req__get_packed_size(NULL, req); uint8_t msg_buf[msg_len]; rw_status_t status; netconf_req__pack(NULL, req, msg_buf); if (rwcli_agent_ch.in.fd.write == -1) { RWTRACE_CRIT(rwcli_trace, RWTRACE_CATEGORY_RWCLI, "Messaging not initialized, failed to execute the command"); return RW_STATUS_FAILURE; } // Consume any prvious unread messages on the stream consume_unread_agent_messages(); // TODO handle EPIPE write(rwcli_agent_ch.in.fd.write, (const void*)(&msg_len), sizeof(unsigned)); write(rwcli_agent_ch.in.fd.write, msg_buf, msg_len); RWTRACE_DEBUG(rwcli_trace, RWTRACE_CATEGORY_RWCLI, "\nSHELL: sent %d bytes to CLI-AGENT", msg_len); status = recv_msg_from_agent(&msg_len); if (status != RW_STATUS_SUCCESS) { *rsp = NULL; return status; } RWTRACE_DEBUG(rwcli_trace, RWTRACE_CATEGORY_RWCLI, "\nSHELL: received %u bytes from CLI-AGENT msglen\n", msg_len); rw_resp = netconf_rsp__unpack(NULL, msg_len, recv_buf); if (rw_resp == NULL) { RWTRACE_ERROR(rwcli_trace, RWTRACE_CATEGORY_RWCLI, "\nReceived message unpack failed\n"); *rsp = NULL; return RW_STATUS_FAILURE; } *rsp = rw_resp; return RW_STATUS_SUCCESS; }
/** * Executes a request towards the specified agent and receives the response. * The response is stored in rwcli_controller.recv_buf. * * @param[in] inst - Controller instance * @param[in] agent_type - Agent on which the command is to be executed * @param[in] msg_type - Message type * @param[in] msg_buf - Reqest payload (encoded) * @param[in] msg_len - Size of the Request payload * @param[out] recv_msg_len - Size of the received message (encoded) * * @returns RW_STATUS_SUCCESS on success, RW_STATUS_FAILURE otherwise. */ static rw_status_t controller_execute( rwcli_controller_t* inst, rwcli_transport_mode_t agent_type, rwcli_msg_type_t msg_type, uint8_t* msg_buf, unsigned msg_len, unsigned* recv_msg_len) { rw_status_t status = RW_STATUS_SUCCESS; if (!controller_is_channel_initialized(inst, agent_type)) { RWTRACE_CRIT(inst->trace_ctxt, RWTRACE_CATEGORY_RWCLI, "Messaging not initialized, failed to execute the command"); return RW_STATUS_FAILURE; } // Consume any previous unread messages on the stream controller_consume_unread_agent_messages(inst, agent_type); status = controller_send_to_agent(inst, agent_type, msg_type, msg_buf, msg_len); if (status != RW_STATUS_SUCCESS) { return status; } RWTRACE_DEBUG(inst->trace_ctxt, RWTRACE_CATEGORY_RWCLI, "\nSHELL: sent %d bytes to CLI-AGENT", msg_len); status = controller_recv_from_agent(inst, agent_type, recv_msg_len); if (status != RW_STATUS_SUCCESS) { return status; } RWTRACE_DEBUG(inst->trace_ctxt, RWTRACE_CATEGORY_RWCLI, "\nSHELL: received %u bytes from CLI-AGENT msglen\n", *recv_msg_len); return status; }
/* * appconf register xpath */ rw_status_t rwdts_appconf_register_xpath_gi(rwdts_appconf_t* ac, const char* xpath, uint32_t flags, rwdts_appconf_prepare_cb_gi prepare, void *prepare_ud, GDestroyNotify prepare_dtor, rwdts_member_reg_handle_t* handle) { rw_status_t rs; rw_keyspec_path_t *keyspec = NULL; const rw_yang_pb_schema_t* schema = NULL; rwdts_api_t *apih; RW_ASSERT_TYPE(ac, rwdts_appconf_t); apih = ac->apih; RW_ASSERT_TYPE(apih, rwdts_api_t); /* Find the schema */ schema = rwdts_api_get_ypbc_schema(apih); if (!schema) { RWTRACE_CRIT(apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "register_xpath[%s] failed - Schema is NULL", xpath); return(RW_STATUS_SUCCESS); } /* Create keyspec from xpath */ keyspec = rw_keyspec_path_from_xpath(schema, (char*)xpath, RW_XPATH_KEYSPEC, &apih->ksi); if (!keyspec) { RWTRACE_CRIT(apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "keyspec from xpath failed for xpath[%s]", xpath); return (RW_STATUS_FAILURE); } RW_ASSERT(keyspec != NULL); RwSchemaCategory cat = rw_keyspec_path_get_category(keyspec); if (cat == RW_SCHEMA_CATEGORY_ANY) { rw_keyspec_path_set_category(keyspec, NULL, RW_SCHEMA_CATEGORY_CONFIG); cat = RW_SCHEMA_CATEGORY_CONFIG; } if (cat != RW_SCHEMA_CATEGORY_CONFIG) { RWTRACE_CRIT(apih->rwtrace_instance, RWTRACE_CATEGORY_RWTASKLET, "keyspec with wrong category xpath[%s]", xpath); RW_ASSERT_MESSAGE(0,"%s:Wrong xpath in appconf register %s", apih->client_path, xpath); return (RW_STATUS_FAILURE); } rs = rwdts_appconf_register_keyspec_gi(ac, keyspec, flags, prepare, prepare_ud, prepare_dtor, handle); rw_keyspec_path_free(keyspec, NULL); return(rs); }