00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <interface/interface.h>
00025
00026 #include <interface/mediators/interface_mediator.h>
00027 #include <interface/mediators/message_mediator.h>
00028 #include <core/threading/refc_rwlock.h>
00029 #include <core/exceptions/system.h>
00030
00031 #include <cstring>
00032 #include <cstdio>
00033 #include <cstdlib>
00034 #include <typeinfo>
00035
00036 namespace fawkes {
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 InterfaceWriteDeniedException::InterfaceWriteDeniedException(const char *type,
00050 const char *id,
00051 const char *msg)
00052 : Exception("This interface instance '%s' of type '%s' is not opened for writing. %s",
00053 id, type, msg)
00054 {
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 InterfaceMessageEnqueueException::InterfaceMessageEnqueueException(const char *type,
00068 const char *id)
00069 : Exception("This interface instance '%s' of type '%s' IS opened for writing, but "
00070 "messages can only be enqueued on reading interfaces.", id, type)
00071 {
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 InterfaceInvalidMessageException::InterfaceInvalidMessageException(const Interface *interface,
00085 const Message *message)
00086 : Exception("Message of type '%s' cannot be enqueued in interface of type '%s'",
00087 message->type(), interface->type())
00088 {
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 InterfaceInvalidException::InterfaceInvalidException(const Interface *interface,
00103 const char *method)
00104 : Exception("The interface %s (instance serial %u) is invalid. You cannot call %s anymore.",
00105 interface->uid(), interface->serial(), method)
00106 {
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 Interface::Interface()
00155 {
00156 __write_access = false;
00157 __rwlock = NULL;
00158 __valid = true;
00159 __next_message_id = 0;
00160 __num_fields = 0;
00161 __fieldinfo_list = NULL;
00162 __messageinfo_list = NULL;
00163 memset(__hash, 0, __INTERFACE_HASH_SIZE);
00164 memset(__hash_printable, 0, __INTERFACE_HASH_SIZE * 2 + 1);
00165
00166 data_ptr = NULL;
00167 data_size = 0;
00168
00169 __message_queue = new MessageQueue();
00170 }
00171
00172
00173
00174 Interface::~Interface()
00175 {
00176 if ( __rwlock) __rwlock->unref();
00177 delete __message_queue;
00178
00179 interface_fieldinfo_t *finfol = __fieldinfo_list;
00180 while ( finfol ) {
00181 __fieldinfo_list = __fieldinfo_list->next;
00182 free(finfol);
00183 finfol = __fieldinfo_list;
00184 }
00185
00186 interface_messageinfo_t *minfol = __messageinfo_list;
00187 while ( minfol ) {
00188 __messageinfo_list = __messageinfo_list->next;
00189 free(minfol);
00190 minfol = __messageinfo_list;
00191 }
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 const unsigned char *
00201 Interface::hash() const
00202 {
00203 return __hash;
00204 }
00205
00206
00207
00208
00209
00210 const char *
00211 Interface::hash_printable() const
00212 {
00213 return __hash_printable;
00214 }
00215
00216
00217
00218
00219
00220 void
00221 Interface::set_hash(unsigned char *ihash)
00222 {
00223 memcpy(__hash, ihash, __INTERFACE_HASH_SIZE);
00224 for (size_t s = 0; s < __INTERFACE_HASH_SIZE; ++s) {
00225 snprintf(&__hash_printable[s*2], 3, "%02X", __hash[s]);
00226 }
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 void
00240 Interface::add_fieldinfo(interface_fieldtype_t type, const char *name,
00241 size_t length, void *value)
00242 {
00243 interface_fieldinfo_t *infol = __fieldinfo_list;
00244 interface_fieldinfo_t *newinfo = (interface_fieldinfo_t *)malloc(sizeof(interface_fieldinfo_t));
00245
00246 newinfo->type = type;
00247 newinfo->name = name;
00248 newinfo->length = length;
00249 newinfo->value = value;
00250 newinfo->next = NULL;
00251
00252 if ( infol == NULL ) {
00253
00254 __fieldinfo_list = newinfo;
00255 } else {
00256
00257 while ( infol->next != NULL ) {
00258 infol = infol->next;
00259 }
00260 infol->next = newinfo;
00261 }
00262
00263 ++__num_fields;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273 void
00274 Interface::add_messageinfo(const char *type)
00275 {
00276 interface_messageinfo_t *infol = __messageinfo_list;
00277 interface_messageinfo_t *newinfo = (interface_messageinfo_t *)malloc(sizeof(interface_messageinfo_t));
00278
00279 newinfo->type = type;
00280 newinfo->next = NULL;
00281
00282 if ( infol == NULL ) {
00283
00284 __messageinfo_list = newinfo;
00285 } else {
00286
00287 while ( infol->next != NULL ) {
00288 infol = infol->next;
00289 }
00290 infol->next = newinfo;
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299 std::list<const char *>
00300 Interface::get_message_types()
00301 {
00302 std::list<const char *> types;
00303 interface_messageinfo_t *cur = __messageinfo_list;
00304
00305 while ( cur != NULL ) {
00306 types.push_back(cur->type);
00307 cur = cur->next;
00308 }
00309
00310 return types;
00311 }
00312
00313
00314
00315
00316
00317
00318 size_t
00319 Interface::hash_size() const
00320 {
00321 return __INTERFACE_HASH_SIZE;
00322 }
00323
00324
00325
00326
00327
00328
00329 const void *
00330 Interface::datachunk() const
00331 {
00332 return data_ptr;
00333 }
00334
00335
00336
00337
00338
00339 bool
00340 Interface::is_writer() const
00341 {
00342 return __write_access;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352 void
00353 Interface::set_validity(bool valid)
00354 {
00355 __rwlock->lock_for_write();
00356 __valid = valid;
00357 __rwlock->unlock();
00358 }
00359
00360
00361
00362
00363
00364 bool
00365 Interface::is_valid() const
00366 {
00367 return __valid;
00368 }
00369
00370
00371
00372
00373
00374 void
00375 Interface::read()
00376 {
00377 __rwlock->lock_for_read();
00378 if ( __valid ) {
00379 memcpy(data_ptr, __mem_data_ptr, data_size);
00380 } else {
00381 __rwlock->unlock();
00382 throw InterfaceInvalidException(this, "read()");
00383 }
00384 __rwlock->unlock();
00385 }
00386
00387
00388
00389
00390
00391 void
00392 Interface::write()
00393 {
00394 if ( ! __write_access ) {
00395 throw InterfaceWriteDeniedException(__type, __id, "Cannot write.");
00396 }
00397
00398 __rwlock->lock_for_write();
00399 if ( __valid ) {
00400 memcpy(__mem_data_ptr, data_ptr, data_size);
00401 } else {
00402 __rwlock->unlock();
00403 throw InterfaceInvalidException(this, "write()");
00404 }
00405 __rwlock->unlock();
00406
00407 __interface_mediator->notify_of_data_change(this);
00408 }
00409
00410
00411
00412
00413
00414 unsigned int
00415 Interface::datasize() const
00416 {
00417 return data_size;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 void
00427 Interface::set_type_id(const char *type, const char *id)
00428 {
00429 strncpy(__type, type, __INTERFACE_TYPE_SIZE);
00430 strncpy(__id, id, __INTERFACE_ID_SIZE);
00431 snprintf(__uid, __INTERFACE_UID_SIZE, "%s::%s", type, id);
00432 }
00433
00434
00435
00436
00437
00438 void
00439 Interface::set_instance_serial(unsigned short instance_serial)
00440 {
00441 __instance_serial = instance_serial;
00442 }
00443
00444
00445
00446
00447
00448
00449 void
00450 Interface::set_mediators(InterfaceMediator *iface_mediator, MessageMediator *msg_mediator)
00451 {
00452 __interface_mediator = iface_mediator;
00453 __message_mediator = msg_mediator;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 void
00463 Interface::set_memory(unsigned int serial, void *real_ptr, void *data_ptr)
00464 {
00465 __mem_serial = serial;
00466 __mem_real_ptr = real_ptr;
00467 __mem_data_ptr = data_ptr;
00468 }
00469
00470
00471
00472
00473
00474
00475 void
00476 Interface::set_readwrite(bool write_access, RefCountRWLock *rwlock)
00477 {
00478 __write_access = write_access;
00479 __rwlock = rwlock;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 bool
00494 Interface::operator==(Interface &comp) const
00495 {
00496 return ( (strncmp(__type, comp.__type, sizeof(__type)) == 0) &&
00497 (strncmp(__id, comp.__id, sizeof(__id)) == 0) );
00498 }
00499
00500
00501
00502
00503
00504
00505 bool
00506 Interface::oftype(const char *interface_type) const
00507 {
00508 return (strncmp(this->__type, interface_type, sizeof(this->__type)) == 0);
00509 }
00510
00511
00512
00513
00514
00515 const char *
00516 Interface::type() const
00517 {
00518 return __type;
00519 }
00520
00521
00522
00523
00524
00525 const char *
00526 Interface::id() const
00527 {
00528 return __id;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 const char *
00540 Interface::uid() const
00541 {
00542 return __uid;
00543 }
00544
00545
00546
00547
00548
00549 unsigned short
00550 Interface::serial() const
00551 {
00552 return __instance_serial;
00553 }
00554
00555
00556
00557
00558
00559 unsigned int
00560 Interface::mem_serial() const
00561 {
00562 return __mem_serial;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 void
00575 Interface::set_from_chunk(void *chunk)
00576 {
00577
00578
00579
00580 memcpy(data_ptr, chunk, data_size);
00581 }
00582
00583
00584
00585
00586
00587
00588 bool
00589 Interface::has_writer() const
00590 {
00591 return __interface_mediator->exists_writer(this);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 unsigned int
00615 Interface::num_readers() const
00616 {
00617 return __interface_mediator->num_readers(this);
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 unsigned int
00634 Interface::msgq_enqueue(Message *message)
00635 {
00636 if ( __write_access ) {
00637 throw InterfaceMessageEnqueueException(__type, __id);
00638 }
00639
00640 if ( message_valid(message) ) {
00641 message->set_interface(this);
00642 message->set_id(next_msg_id());
00643
00644 __message_mediator->transmit(message);
00645 unsigned int msgid = message->id();
00646 message->unref();
00647 return msgid;
00648 } else {
00649 throw InterfaceInvalidMessageException(this, message);
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 unsigned int
00669 Interface::msgq_enqueue_copy(Message *message)
00670 {
00671 if ( __write_access ) {
00672 throw InterfaceMessageEnqueueException(__type, __id);
00673 }
00674 if ( message == NULL ) {
00675 throw NullPointerException("Message may not be NULL");
00676 }
00677
00678 if ( message_valid(message) ) {
00679 Message *mcopy = message->clone();
00680 mcopy->set_interface(this);
00681 mcopy->set_id(next_msg_id());
00682 __message_mediator->transmit(mcopy);
00683 unsigned int msgid = mcopy->id();
00684 mcopy->unref();
00685 message->set_id(msgid);
00686 return msgid;
00687 } else {
00688 throw InterfaceInvalidMessageException(this, message);
00689 }
00690 }
00691
00692
00693
00694
00695
00696
00697
00698 void
00699 Interface::msgq_append(Message *message)
00700 {
00701 if ( ! __write_access ) {
00702 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00703 "reading instance of an interface (append).");
00704 }
00705
00706 __message_queue->append(message);
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 void
00719 Interface::msgq_remove(Message *message)
00720 {
00721 if ( ! __write_access ) {
00722 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00723 "reading instance of an interface (remove msg).");
00724 }
00725
00726 return __message_queue->remove(message);
00727 }
00728
00729
00730
00731
00732
00733
00734
00735 void
00736 Interface::msgq_remove(unsigned int message_id)
00737 {
00738 if ( ! __write_access ) {
00739 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00740 "reading instance of an interface (remove id).");
00741 }
00742
00743 return __message_queue->remove(message_id);
00744 }
00745
00746
00747
00748
00749
00750
00751 unsigned int
00752 Interface::msgq_size()
00753 {
00754 if ( ! __write_access ) {
00755 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00756 "reading instance of an interface (size).");
00757 }
00758
00759 return __message_queue->size();
00760 }
00761
00762
00763
00764
00765
00766
00767 bool
00768 Interface::msgq_empty()
00769 {
00770 if ( ! __write_access ) {
00771 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00772 "reading instance of an interface (empty).");
00773 }
00774
00775 return __message_queue->empty();
00776 }
00777
00778
00779
00780
00781
00782
00783 void
00784 Interface::msgq_flush()
00785 {
00786 if ( ! __write_access ) {
00787 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00788 "reading instance of an interface (flush).");
00789 }
00790
00791 __message_queue->flush();
00792 }
00793
00794
00795
00796
00797
00798
00799 void
00800 Interface::msgq_lock()
00801 {
00802 if ( ! __write_access ) {
00803 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00804 "reading instance of an interface (lock).");
00805 }
00806
00807 __message_queue->lock();
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817 bool
00818 Interface::msgq_try_lock()
00819 {
00820 if ( ! __write_access ) {
00821 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00822 "reading instance of an interface (try_lock).");
00823 }
00824
00825 return __message_queue->try_lock();
00826 }
00827
00828
00829
00830
00831
00832
00833 void
00834 Interface::msgq_unlock()
00835 {
00836 if ( ! __write_access ) {
00837 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00838 "reading instance of an interface (unlock).");
00839 }
00840
00841 __message_queue->unlock();
00842 }
00843
00844
00845
00846
00847
00848
00849
00850 MessageQueue::MessageIterator
00851 Interface::msgq_begin()
00852 {
00853 if ( ! __write_access ) {
00854 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00855 "reading instance of an interface (begin).");
00856 }
00857
00858 return __message_queue->begin();
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868 MessageQueue::MessageIterator
00869 Interface::msgq_end()
00870 {
00871 if ( ! __write_access ) {
00872 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00873 "reading instance of an interface (end).");
00874 }
00875
00876 return __message_queue->end();
00877 }
00878
00879
00880
00881
00882
00883
00884 Message *
00885 Interface::msgq_first()
00886 {
00887 if ( ! __write_access ) {
00888 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00889 "reading instance of an interface (first).");
00890 }
00891
00892 return __message_queue->first();
00893 }
00894
00895
00896
00897
00898 void
00899 Interface::msgq_pop()
00900 {
00901 if ( ! __write_access ) {
00902 throw InterfaceWriteDeniedException(__type, __id, "Cannot work on message queue on "
00903 "reading instance of an interface (pop).");
00904 }
00905
00906 __message_queue->pop();
00907 }
00908
00909
00910
00911
00912
00913 InterfaceFieldIterator
00914 Interface::fields()
00915 {
00916 return InterfaceFieldIterator(__fieldinfo_list);
00917 }
00918
00919
00920
00921
00922
00923 InterfaceFieldIterator
00924 Interface::fields_end()
00925 {
00926 return InterfaceFieldIterator();
00927 }
00928
00929
00930
00931
00932
00933 unsigned int
00934 Interface::num_fields()
00935 {
00936 return __num_fields;
00937 }
00938
00939 }