Commit 99d934ff authored by claes's avatar claes

*** empty log message ***

parent 310c85e3
/*
* Proview $Id: opc_provider.cpp,v 1.5 2007-03-13 15:48:41 claes Exp $
* Proview $Id: opc_provider.cpp,v 1.6 2007-03-15 08:07:50 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
......@@ -41,6 +41,8 @@
#define START_OIX 1000
#define procom_obj_mFlags_Analog (1 << 31)
typedef map<pwr_tUInt32, opcprv_sub>::iterator sublist_iterator;
static pwr_tVid opc_vid;
static char opc_vname[32];
static char opc_endpoint[256];
......@@ -577,12 +579,131 @@ void opc_provider::readAttribute( co_procom *pcom, pwr_tOix oix, unsigned int of
void opc_provider::subAssociateBuffer( co_procom *pcom, void **buff, int oix, int offset,
int size, pwr_tSubid sid)
{
if ( oix < (int)m_list.size())
*buff = (char *)m_list[oix].po.body + offset;
else
if ( oix >= (int)m_list.size()) {
*buff = 0;
return;
}
*buff = (char *)m_list[oix].po.body + offset;
switch ( m_list[oix].po.cid) {
case pwr_cClass_Opc_String:
case pwr_cClass_Opc_Boolean:
case pwr_cClass_Opc_Float:
case pwr_cClass_Opc_Double:
case pwr_cClass_Opc_Decimal:
case pwr_cClass_Opc_Long:
case pwr_cClass_Opc_Int:
case pwr_cClass_Opc_Short:
case pwr_cClass_Opc_Byte:
case pwr_cClass_Opc_UnsignedLong:
case pwr_cClass_Opc_UnsignedInt:
case pwr_cClass_Opc_UnsignedShort:
case pwr_cClass_Opc_UnsignedByte:
case pwr_cClass_Opc_Base64Binary:
case pwr_cClass_Opc_Time:
case pwr_cClass_Opc_Date:
case pwr_cClass_Opc_Duration:
case pwr_cClass_Opc_QName:
if ( *buff == ((pwr_sClass_Opc_String *)m_list[oix].po.body)->Value) {
// Add opc subscription
_ns1__Subscribe subscribe;
_ns1__SubscribeResponse subscribe_response;
char handle[20];
subscribe.Options = new ns1__RequestOptions();
subscribe.Options->ReturnItemTime = (bool *) malloc( sizeof(bool));
*subscribe.Options->ReturnItemTime = true;
subscribe.ItemList = new ns1__SubscribeRequestItemList();
ns1__SubscribeRequestItem *ritem = new ns1__SubscribeRequestItem();
ritem->ItemName = new std::string( m_list[oix].item_name);
sprintf( handle, "%d", oix);
ritem->ClientItemHandle = new std::string( handle);
ritem->RequestedSamplingRate = (int *) malloc( sizeof(int));
*ritem->RequestedSamplingRate = 1000;
subscribe.ItemList->Items.push_back( ritem);
if ( soap_call___ns1__Subscribe( &soap, opc_endpoint, NULL, &subscribe, &subscribe_response) ==
SOAP_OK) {
opcprv_sub sub;
sub.handle = *subscribe_response.ServerSubHandle;
sub.oix = oix;
m_sublist[sid.rix] = sub;
if ( subscribe_response.RItemList && subscribe_response.RItemList->Items.size()) {
for ( int i = 0; i < (int)subscribe_response.RItemList->Items.size(); i++) {
// subscribe_response.RItemList->Items[i]->ItemValue...
}
}
}
}
break;
default: ;
}
}
// Rt only
void opc_provider::subDisassociateBuffer( co_procom *pcom, pwr_tSubid sid)
{
sublist_iterator it = m_sublist.find( sid.rix);
if ( it != m_sublist.end()) {
// Cancel subscription
_ns1__SubscriptionCancel subcancel;
_ns1__SubscriptionCancelResponse subcancel_response;
subcancel.ServerSubHandle = new std::string(it->second.handle);
if ( soap_call___ns1__SubscriptionCancel( &soap, opc_endpoint, NULL, &subcancel, &subcancel_response) ==
SOAP_OK) {
// Where are the fault codes ???
}
m_sublist.erase( it);
}
}
// Rt only
void opc_provider::cyclic( co_procom *pcom)
{
int size = 0;
_ns1__SubscriptionPolledRefresh subpoll;
_ns1__SubscriptionPolledRefreshResponse subpoll_response;
for ( sublist_iterator it = m_sublist.begin(); it != m_sublist.end(); it++) {
subpoll.ServerSubHandles.push_back( it->second.handle);
size++;
}
if ( size) {
if ( soap_call___ns1__SubscriptionPolledRefresh( &soap, opc_endpoint, NULL, &subpoll, &subpoll_response) ==
SOAP_OK) {
if ( (int) subpoll_response.RItemList.size() != size) {
return;
}
int idx = 0;
for ( sublist_iterator it = m_sublist.begin(); it != m_sublist.end(); it++) {
if ( subpoll_response.RItemList[idx]->Items.size()) {
switch ( m_list[it->second.oix].po.cid) {
case pwr_cClass_Opc_String:
strcpy( ((pwr_sClass_Opc_String *)m_list[it->second.oix].po.body)->Value,
subpoll_response.RItemList[idx]->Items[0]->Value);
break;
default: ;
}
}
idx++;
}
}
}
}
// Wb only
void opc_provider::commit( co_procom *pcom)
{
......
/*
* Proview $Id: opc_provider.h,v 1.5 2007-03-13 15:48:41 claes Exp $
* Proview $Id: opc_provider.h,v 1.6 2007-03-15 08:07:50 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
......@@ -20,6 +20,7 @@
#ifndef opc_provider_h
#define opc_provider_h
#include <map.h>
#include "co_provider.h"
#include "co_procom.h"
#include "pwr_opcclasses.h"
......@@ -43,6 +44,12 @@ class opcprv_obj {
}
};
class opcprv_sub {
public:
pwr_tOix oix;
std::string handle;
};
class opc_provider : public co_provider {
public:
opc_provider( pvd_eEnv env = pvd_eEnv_Wb) : co_provider(env), root(0), next_oix(1) {
......@@ -66,6 +73,8 @@ public:
unsigned int size);
virtual void subAssociateBuffer( co_procom *pcom, void **buff, int oix, int offset,
int size, pwr_tSubid sid);
virtual void subDisassociateBuffer( co_procom *pcom, pwr_tSubid sid);
virtual void cyclic( co_procom *pcom);
virtual void commit( co_procom *pcom);
virtual void abort( co_procom *pcom);
......@@ -86,6 +95,7 @@ public:
void errlog( std::string* item, std::vector<ns1__OPCError *>& errvect);
vector<opcprv_obj> m_list;
map<pwr_tUInt32, opcprv_sub> m_sublist;
pwr_tOix root;
pwr_tOix next_oix;
struct soap soap;
......
/*
* Proview $Id: opc_server.cpp,v 1.6 2007-03-14 08:02:16 claes Exp $
* Proview $Id: opc_server.cpp,v 1.7 2007-03-15 08:07:50 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
......@@ -17,6 +17,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <map.h>
#include <net/if.h>
#include <net/if_arp.h>
......@@ -35,12 +36,57 @@ typedef struct {
int access;
} opc_sClientAccess;
class opcsrv_sub {
public:
void *p;
int size;
opc_eDataType opc_type;
pwr_eType pwr_type;
pwr_tSubid subid;
};
class opcsrv_client {
public:
pwr_tTime m_last_time;
map< std::string, vector<opcsrv_sub> > m_sublist;
};
typedef map< std::string, vector<opcsrv_sub> >::iterator sublist_iterator;
typedef map< int, opcsrv_client>::iterator client_iterator;
class opc_server {
public:
map< int, opcsrv_client> m_client;
opcsrv_client *find_client( int sid);
opcsrv_client *new_client( int sid);
};
static opc_server *opcsrv;
static pwr_tTime opc_start_time;
static pwr_sClass_Opc_ServerConfig *opc_config;
static opc_sClientAccess opc_client_access[20];
static int opc_client_access_cnt = 0;
static int opc_current_access;
opcsrv_client *opc_server::find_client( int sid)
{
client_iterator it = opcsrv->m_client.find( sid);
if ( it == opcsrv->m_client.end())
return 0;
else
return &it->second;
}
opcsrv_client *opc_server::new_client( int sid)
{
opcsrv_client client;
m_client[sid] = client;
return &m_client[sid];
}
int main()
{
......@@ -53,6 +99,8 @@ int main()
exit(sts);
}
opcsrv = new opc_server();
#if 0
pwr_tOid config_oid;
......@@ -266,24 +314,123 @@ SOAP_FMAC5 int SOAP_FMAC6 __ns1__Write(struct soap*,
return 0;
}
SOAP_FMAC5 int SOAP_FMAC6 __ns1__Subscribe(struct soap*,
SOAP_FMAC5 int SOAP_FMAC6 __ns1__Subscribe(struct soap* soap,
_ns1__Subscribe *ns1__Subscribe,
_ns1__SubscribeResponse *ns1__SubscribeResponse)
{
pwr_tStatus sts;
pwr_tTypeId a_tid;
pwr_tUInt32 a_size, a_offs, a_elem;
pwr_tAName aname;
opcsrv_client *client = opcsrv->find_client( soap->ip);
if ( !client)
client = opcsrv->new_client( soap->ip);
clock_gettime( CLOCK_REALTIME, &client->m_last_time);
if ( ns1__Subscribe->ItemList) {
for ( int i = 0; i < (int) ns1__Subscribe->ItemList->Items.size(); i++) {
opcsrv_sub sub;
strcpy( aname, ns1__Subscribe->ItemList->Items[0]->ItemName->c_str());
sts = gdh_GetAttributeCharacteristics( aname, &a_tid, &a_size, &a_offs, &a_elem);
if ( EVEN(sts)) {
// TODO Set the fault code somewhere...
continue;
}
sub.size = a_size;
sub.pwr_type = (pwr_eType) a_tid; // TODO
if ( !opc_pwrtype_to_opctype( sub.pwr_type, (int *)&sub.opc_type))
printf( "Type error %s\n", aname);
sts = gdh_RefObjectInfo( aname, &sub.p, &sub.subid, sub.size);
if ( EVEN(sts)) {
// TODO
continue;
}
if ( i == 0) {
vector<opcsrv_sub> subv;
ns1__SubscribeResponse->ServerSubHandle =
new std::string( cdh_SubidToString( 0, sub.subid, 0));
client->m_sublist[*ns1__SubscribeResponse->ServerSubHandle] = subv;
}
client->m_sublist[*ns1__SubscribeResponse->ServerSubHandle].push_back( sub);
}
}
return 0;
}
SOAP_FMAC5 int SOAP_FMAC6 __ns1__SubscriptionPolledRefresh(struct soap*,
SOAP_FMAC5 int SOAP_FMAC6 __ns1__SubscriptionPolledRefresh(struct soap* soap,
_ns1__SubscriptionPolledRefresh *ns1__SubscriptionPolledRefresh,
_ns1__SubscriptionPolledRefreshResponse *ns1__SubscriptionPolledRefreshResponse)
{
pwr_tTime current_time;
opcsrv_client *client = opcsrv->find_client( soap->ip);
if ( !client) {
// TODO
return 0;
}
clock_gettime( CLOCK_REALTIME, &current_time);
client->m_last_time = current_time;
for ( int i = 0; i < (int) ns1__SubscriptionPolledRefresh->ServerSubHandles.size(); i++) {
sublist_iterator it =
client->m_sublist.find( ns1__SubscriptionPolledRefresh->ServerSubHandles[i]);
if ( it != client->m_sublist.end()) {
ns1__SubscribePolledRefreshReplyItemList *rlist = new ns1__SubscribePolledRefreshReplyItemList();
rlist->SubscriptionHandle = new std::string(ns1__SubscriptionPolledRefresh->ServerSubHandles[i]);
for ( int j = 0; j < (int)it->second.size(); j++) {
ns1__ItemValue *ritem = new ns1__ItemValue();
// TODO
ritem->Value = (char *) malloc( 80);
strcpy( ritem->Value, "1");
strcpy( ritem->ValueType, "xsd:string");
ritem->Timestamp = (time_t *) malloc( sizeof(time_t));
*ritem->Timestamp = current_time.tv_sec;
rlist->Items.push_back( ritem);
}
ns1__SubscriptionPolledRefreshResponse->RItemList.push_back( rlist);
}
else {
}
}
return 0;
}
SOAP_FMAC5 int SOAP_FMAC6 __ns1__SubscriptionCancel(struct soap*,
SOAP_FMAC5 int SOAP_FMAC6 __ns1__SubscriptionCancel(struct soap* soap,
_ns1__SubscriptionCancel *ns1__SubscriptionCancel,
_ns1__SubscriptionCancelResponse *ns1__SubscriptionCancelResponse)
{
opcsrv_client *client = opcsrv->find_client( soap->ip);
if ( !client) {
// TODO
return 0;
}
clock_gettime( CLOCK_REALTIME, &client->m_last_time);
sublist_iterator it =
client->m_sublist.find( *ns1__SubscriptionCancel->ServerSubHandle);
if ( it != client->m_sublist.end()) {
client->m_sublist.erase( it);
}
else {
// TODO Set the fault code somewhere...
}
ns1__SubscriptionCancelResponse->ClientRequestHandle =
ns1__SubscriptionCancel->ClientRequestHandle;
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment