/usr/include/biblesync/biblesync.hh is in libbiblesync-dev 1.1.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | /*
* BibleSync library
* biblesync.hh
*
* Karl Kleinpaste, May 2014
*
* All files related to implementation of BibleSync, including program
* source, READMEs, manual pages, and related similar documents, are in
* the public domain. As a matter of simple decency, your social
* obligations are to credit the source and to coordinate any changes you
* make back to the origin repository. These obligations are non-
* binding for public domain software, but they are to be seriously
* handled nonetheless.
*/
#ifndef __BIBLESYNC_HH__
#define __BIBLESYNC_HH__
#include <libintl.h>
#ifndef _
#define _(x) gettext(x)
#endif
#include "biblesync-version.hh"
//
// Bible Sync Protocol.
// http://biblesyncprotocol.wikispaces.com/
//
// BSP provides a classroom type of arrangement, where one person
// (speaker) is in charge of inducing others' (audience) Bible
// software to navigate as speaker requires. The speaker only
// xmits and the audience only recvs.
// BSP also provides a personal mode which both xmits and recvs, where
// one user works with multiple programs across several devices,
// also suitable for small teams working together, such as translators.
// BSP is implemented using multicast UDP with small packets in a
// simple format employing a few bytes of packet control followed by a
// series of newline-terminated "name=value" pairs.
//
// * Application interface *
//
// - object creation.
// BibleSync *YourBibleSyncObjectPtr = new BibleSync(app, version, user);
// create exactly one.
// identify the application, its version, and the user.
//
// - mode selection.
// setMode(BSP_MODE_xyz, your_void_nav_func, "passphrase");
// invoke a mode, including net.setup as needed.
// xyz = { DISABLE, PERSONAL, SPEAKER, AUDIENCE }.
// DISABLE kills it, shuts off network access.
// PERSONAL is bidirectional.
// SPEAKER xmits only.
// AUDIENCE recvs only.
// => empty passphrase ("") means re-use existing passphrase.
// => for any active mode, the application must then start polling using
// the receiver, BibleSync::Receive(), and stop polling when mode
// goes to DISABLE. if Receive() is called while disabled, it will
// return FALSE to indicate its polled use should stop, otherwise TRUE.
// => interface for your_void_nav_func:
// (char cmd, string speakerkey,
// string bible, string ref, string alt,
// string group, string domain,
// string info, string dump)
// there are 6 your_void_nav_func() use cases, identified in cmd.
// non-error cases provide valid speakerkey (UUID), else it is "".
// 1. 'A' (announce)
// presence message in alt. dump available.
// 2. 'N' (navigation)
// bible, ref, alt, group, domain as arrived.
// info + dump available.
// 3. 'M' (mismatch) against passphrase or mode or listen status.
// info == "announce" or "sync" or "beacon" (+ user @ [ipaddr])
// sync: bible, ref, alt, group, domain as arrived.
// announce: presence message in alt.
// also, individual elements are also available:
// overload: bible ref group domain
// user [ipaddr] app+ver device
// dump available.
// 4. 'S' (new speaker)
// param overload as above. alt unused. see listenToSpeaker().
// 5. 'D' (dead speaker)
// opposite of new speaker. only param is speakerkey.
// 6. 'E' (error) for network errors & malformed packets.
// only info + dump are useful.
//
// - get current mode.
// BibleSync_mode getMode().
//
// - get current passphrase, for default use when setting a new one.
// string getPassphrase().
//
// - receive navigation.
// BibleSync::Receive(YourBibleSyncObjPtr); // *-* poll often *-*
// see note below; calls your_void_nav_func().
//
// - send navigation.
// BibleSync_xmit_status retval =
// Transmit(BSP_SYNC,
// "NASB", "John.3.16", "some alt ref",
// "1", "BIBLE-VERSE");
// params: type (sync only), bible, ref, alt-ref, group, domain.
// all params have defaults.
// => it is the application's responsibility to send well-formed verse
// references.
//
// - set self as private
// bool setPrivate(boolean);
// sets outgoing TTL to zero so no one hears you off-machine.
// applicable only to BSP_PERSONAL mode.
//
// - allow another speaker to drive us
// void listenToSpeaker(bool listen, string speakerkey)
// say yes/no to listening.
//
// Receive() USAGE NOTE:
// the application must call BibleSync::Receive(YourBibleSyncObjPtr)
// frequently. For example:
// g_timeout_add(1000, // 1sec in msec.
// (GSourceFunc)BibleSync::Receive,
// biblesyncobj); // of type (BibleSync *).
// g_timeout_add is a glib function for polled function calls.
// this will induce timed-interval calls to the function, as long
// as the function returns TRUE; upon returning FALSE, calls stop.
// other than with glib, accomplish the same thing somehow else.
// Receive is a static method accessible from C or C++. it must be
// called with the pointer to your BibleSync object in order that
// object context be re-entered. the internal receive routine
// is private.
//
// Note on speaker beacons:
// Protocol operates using periodic (10sec) beacons of speaker availability.
// By default, PERSONAL & AUDIENCE accepts listening to 1st announced speaker,
// thereafter ignores any more, but includes them in the list of available
// speakers and notifies the app of their availability (see above, 'S'/'D').
// Override this behavior choice however desired, using listenToSpeaker() in
// reaction to 'S' events or on user request.
// Speakers who stop xmitting beacons will timeout, be declared dead, and
// removed after 30sec beacon silence, with app notification ('D').
// Observe that pure Speaker clears the speaker list and by default ignores
// all newly-identified claimants to speaker status. Again, this is default
// behavior, but it makes no sense to try to listen to one as the mode is
// a mismatch.
// Note also that Personal is both speaker and audience.
#include <map>
#include <string>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#ifndef WIN32
#include <sys/utsname.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <uuid/uuid.h>
#else
#define uuid_t UUID
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#endif
using namespace std;
typedef enum _BibleSync_mode {
BSP_MODE_DISABLE,
BSP_MODE_PERSONAL,
BSP_MODE_SPEAKER,
BSP_MODE_AUDIENCE,
N_BSP_MODE
} BibleSync_mode;
typedef enum _BibleSync_xmit_status {
BSP_XMIT_OK,
BSP_XMIT_FAILED,
BSP_XMIT_NO_SOCKET,
BSP_XMIT_BAD_TYPE,
BSP_XMIT_NO_AUDIENCE_XMIT,
BSP_XMIT_RECEIVING,
N_BSP_XMIT
} BibleSync_xmit_status;
// args: cmd, speakerkey, bible, verse, alt, group, domain, info, dump.
typedef void (*BibleSync_navigate)(char, string,
string, string, string,
string, string,
string, string);
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
// message structure constants
#define BSP_MULTICAST "239.225.27.227"
#define BSP_PORT 22272
#define BSP_MAX_SIZE 1280 // in spec, it's 512. experimenting.
#define BSP_RES_SIZE 6 // unused bytes, fill out header to 32.
#define BSP_HEADER_SIZE 32
#define BSP_MAX_PAYLOAD (BSP_MAX_SIZE - BSP_HEADER_SIZE)
// message indications
#define BSP_MAGIC htonl(0x409CAF11)
#define BSP_PROTOCOL 2
// message types
#define BSP_ANNOUNCE 1 // presence announcement.
#define BSP_SYNC 2 // navigation synchronization.
#define BSP_BEACON 3 // speaker availability beacon.
// beacon packet is identical to presence announcement except for type.
// beacon constants
#define BSP_BEACON_COUNT 10 // xmit every N calls of Receive().
#define BSP_BEACON_MULTIPLIER 3 // multiplier for aging to death.
// message content names.
#define BSP_APP_NAME "app.name" // req'd
#define BSP_APP_VERSION "app.version" // opt
#define BSP_APP_INSTANCE_UUID "app.inst.uuid" // req'd
#define BSP_APP_OS "app.os" // opt
#define BSP_APP_DEVICE "app.device" // opt
#define BSP_APP_USER "app.user" // req'd
#define BSP_MSG_SYNC_DOMAIN "msg.sync.domain" // req'd
#define BSP_MSG_SYNC_VERSE "msg.sync.verse" // req'd
#define BSP_MSG_SYNC_ALTVERSE "msg.sync.altVerse" // opt
#define BSP_MSG_SYNC_BIBLEABBREV "msg.sync.bibleAbbrev" // req'd
#define BSP_MSG_SYNC_GROUP "msg.sync.group" // req'd
#define BSP_MSG_PASSPHRASE "msg.sync.passPhrase" // req'd
// required number of fields to send (out) or verify (in).
#define BSP_FIELDS_RECV_ANNOUNCE 4
#define BSP_FIELDS_RECV_SYNC 8
#define BSP_FIELDS_XMIT_ANNOUNCE 7
#define BSP_FIELDS_XMIT_SYNC 12
#ifdef linux
# define BSP_OS "Linux"
#else
# ifdef WIN32
# define BSP_OS "Windows"
# else
# define BSP_OS "UNIX"
# endif
#endif
#define BSP_UUID_PRINT_LENGTH 37 // actually 36, plus '\0'.
class BibleSync {
private:
// simple name/value pairs.
typedef std::map < string, string > BibleSyncContent;
typedef struct _BibleSyncMessage {
uint32_t magic;
uint8_t version;
uint8_t msg_type;
uint16_t num_packets;
uint16_t index_packet;
uint8_t reserved[BSP_RES_SIZE];
uuid_t uuid;
char body[BSP_MAX_PAYLOAD+1]; // +1 for stuffing '\0'.
} BibleSyncMessage;
typedef struct _BibleSyncSpeaker {
bool listen; // nav for this guy?
uint8_t countdown; // lifetime aging.
string addr; // for spoof check.
} BibleSyncSpeaker;
// key string is origin uuid.
typedef std::map < string, BibleSyncSpeaker > BibleSyncSpeakerMap;
typedef BibleSyncSpeakerMap::iterator BibleSyncSpeakerMapIterator;
// self identification.
string BibleSync_version;
// application identifiers.
string application;
string version;
string user;
string device;
// currently processing received navigation.
// prevents use of Transmit.
bool receiving;
// when xmit-capable, we xmit BSP_BEACON every N calls of Receive().
uint8_t beacon_countdown;
// track currently-known speaker set.
BibleSyncSpeakerMap speakers;
// what operational mode we're in.
BibleSync_mode mode;
// callback by which Receive induces navigation.
BibleSync_navigate nav_func;
// privacy
string passphrase;
// network access
struct sockaddr_in server, client;
int server_fd, client_fd;
struct ip_mreq multicast_req;
// default address discoverer, for multicast configuration.
void InterfaceAddress();
struct in_addr interface_addr;
// unique identification.
uuid_t uuid;
char uuid_string[BSP_UUID_PRINT_LENGTH]; // printable
// socket init and listener start, called from setMode().
string Setup();
// dispose of network access.
void Shutdown();
// real receiver.
int ReceiveInternal(); // C++ object context.
int InitSelectRead(char *, struct sockaddr_in *, BibleSyncMessage *);
// speaker list management.
void ageSpeakers();
void clearSpeakers();
// uuid dumper;
void uuid_dump(uuid_t &u, char *destination);
char uuid_dump_string[BSP_UUID_PRINT_LENGTH];
void uuid_gen(uuid_t &u); // differentiates linux/win32.
#ifdef linux
// network self-analysis, borrowed from the net.
int get_default_if_name(char *name, socklen_t size);
int parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo);
int readNlSock(int sockFd, char *bufPtr, size_t buf_size,
unsigned int seqNum, unsigned int pId);
#else
// no other support routines needed for Windows/Solaris/BSD.
#endif /* linux */
public:
BibleSync(string a, string v, string u);
~BibleSync();
// operation.
BibleSync_mode setMode(BibleSync_mode m,
BibleSync_navigate n = NULL,
string p = "");
inline BibleSync_mode getMode(void) { return mode; };
// library identification.
inline string getVersion(void) { return BibleSync_version; };
// obtain passphrase, for default choice.
inline string getPassphrase(void) { return passphrase; };
// audience receiver
static int Receive(void *myself); // assume C context: poll from timeout.
// speaker transmitter
BibleSync_xmit_status Transmit(char message_type = BSP_SYNC,
string bible = "KJV",
string ref = "Gen.1.1",
string alt = "",
string group = "1",
string domain = "BIBLE-VERSE");
// set privacy using TTL 0 in personal mode.
bool setPrivate(bool privacy);
// say whether you want to hear from this speaker.
void listenToSpeaker(bool listen, string speakerkey);
};
#endif // __BIBLESYNC_HH__
|