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 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
|
// o2.h -- public header file for o2 system
// Roger B. Dannenberg and Zhang Chi
// see license.txt for license
// June 2016
#ifndef O2_H
#define O2_H
#ifdef __cplusplus
extern "C" {
#endif
/** \file o2.h
\mainpage
\section Introduction
This documentation is divided into modules. Each module describes a
different area of functionality: Basics, Return Codes, Low-Level
Message Send, and Low-Level Message Parsing.
\section Overview
O2 is a communication protocol for interactive music and media
applications. O2 is inspired by Open Sound Control (OSC) and uses
similar means to form addresses, specify types, and encode messages.
However, in addition to providing message delivery, O2 offers a
discovery mechanism where processes automatically discover and connect
to other processes. Each process can offer zero or more named
"services," which are top-level nodes in a global, tree-structured
address space for a distributed O2 application. In O2, services
replace the notion of network addresses (e.g. 128.2.100.57) in OSC.
O2 is based on IP (Internet Protocol), but there are some mechanisms
that allow an O2 process to serve as a bridge to other networks such
as Bluetooth.
O2 addresses begin with the service name. Thus, a complete O2 address
would be written simply as "/synth/filter/cutoff," where "synth" is
the service name.
Furthermore, O2 implements a clock synchronization protocol. A single
process is designated as the "master," and other processes
automatically synchronize their local clocks to the master. All O2
messages are timestamped. Messages are delivered immediately, but
their designated operations are invoked according to the timestamp. A
timestamp of zero (0.0) means deliver the message
immediately. Messages with non-zero timestamps are only deliverable
after both the sender and receiver have synchronized clocks.
A service is created using the functions:
o2_service_new("service_name")
and
o2_method_new("address," "types," handler, user_data, coerce, parse),
where o2_method_new is called to install a handler for each node, and each
"address" includes the service name as the first node.
Some major components and concepts of O2 are the following:
- **Application** - a collection of collaborating processes are called
an "application." Applications are named by a simple ASCII string.
In O2, all components belong to an application, and O2 supports
communication only *within* an application. This allows multiple
independent applications to co-exist and share the same local area
network.
- **Host** - (conventional definition) a host is a computer (virtual
or real) that may host multiple processes. Essentially, a Host is
equivalent to an IP address.
- **Process** - (conventional definition) an address space and one or
more threads. A process can offer one or more O2 services and
can serve as a client of O2 services in the same or other processes.
Each process using O2 has one directory of services shared by all
O2 activity in that process (thus, this O2 implementation can be
thought of as a "singleton" object). The single O2 instance in a
process belongs to one and only one application. O2 does not support
communication between applications.
- **Service** - an O2 service is a named server that receives and acts
upon O2 messages. A service is addressed by name. Multiple services
can exist within one process. A service does not imply a (new) thread
because services are "activated" by calling o2_poll(). It is up to
the programmer ("user") to call o2_poll() frequently, and if this
is done using multiple threads, it is up to the programmer to deal
with all concurrency issues. O2 is not reentrant, so o2_poll() should
be called by only one thread. Since there is at most one O2 instance
per process, a single call to o2_poll() handles all services in the
process.
- **Message** - an O2 message, similar to an OSC message, contains an address
pattern representing a function, a type string and a set of values
representing parameters.
- **Address Pattern** - O2 messages use URL-like addresses, as does OSC,
but the top-level node in the hierarchical address space is the
service name. Thus, to send a message to the "note" node of the
"synth" service, the address pattern might be "/synth/note." The
OSC pattern specification language is used unless the first character
is "!", e.g. "!synth/note" denotes the same address as "/synth/note"
except that O2 can assume that there are no pattern characters such
as "*" or "[".
- **Scheduler** - O2 implements two schedulers for timed message
delivery. Schedulers are served by the same o2_poll() call that
runs other O2 activity. The #o2_gtsched schedules according to the
application's master clock time, but since this depends on clock
synchronization, nothing can be scheduled until clock
synchronization is achieved (typically within a few seconds of
starting the process that provides the master clock). For
local-only services, it is possible to use the #o2_ltsched
scheduler (not with o2_send(), but by explicitly constructing
messages and scheduling them with o2_schedule(). In any case,
scheduling is useful *within* a service for any kind of timed
activity.
*/
// get uint32_t, etc.:
#include <stdlib.h>
#include <stdint.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/** \defgroup debugging Debugging Support
* @{
*/
/// \brief Enable debugging output.
///
/// Unless O2_NO_DEBUG is defined at compile time, O2 is
/// compiled with debugging code that prints information to
/// stdout, including network addresses, services discovered,
/// and clock synchronization status. Enable the debugging
/// information by calling o2_debug_flags() with a string
/// containing any of the following characters:
/// - c - for basic connection data
/// - r - for tracing non-system incoming messages
/// - s - for tracing non-system outgoing messages
/// - R - for tracing system incoming messages
/// - S - for tracing system outgoing messages
/// - k - for tracing clock synchronization protocol
/// - d - for tracing discovery messages
/// - t - for tracing user messages dispatched from schedulers
/// - T - for tracing system messages dispatched from schedulers
/// - m - trace O2_MALLOC and O2_FREE calls
/// - o - trace socket creating and closing
/// - O - open sound control messages
/// - g - print general status info
/// - a - all debug flags except m (malloc/free)
#ifndef O2_NO_DEBUG
void o2_debug_flags(const char *flags);
#endif
/** @} */
/** \defgroup returncodes Return Codes
* @{
*/
// Status return values used in o2 functions
#define O2_SUCCESS 0 ///< function was successful
/// \brief an error return value: a non-specific error occurred.
///
/// In general, any return value < 0 indicates an error. Testing for
/// only O2_FAIL will not detect more specific error return values
/// such as O2_SERVICE_CONFLICT, O2_NO_MEMORY, etc.
#define O2_FAIL (-1)
// TODO: this value is never used/returned
/// an error return value: path to handler specifies a remote service
#define O2_SERVICE_CONFLICT (-2)
// TODO: this value is never used/returned
/// an error return value: path to handler specifies non-existant service
#define O2_NO_SERVICE (-3)
/// an error return value: process is out of free memory
#define O2_NO_MEMORY (-4)
/// an error return value for o2_initialize(): O2 is already running.
#define O2_ALREADY_RUNNING (-5)
/// an error return value for o2_initialize(): invalid name parameter.
#define O2_BAD_NAME (-6)
/// an error return value for o2_add_vector(): invalid element type
#define O2_BAD_TYPE (-7)
/// \brief an error return value: mismatched types and arguments
/// returned by o2_message_build(), o2_send(), o2_send_cmd()
#define O2_BAD_ARGS (-8)
/// an error return value for o2_initialize(): the socket is closed.
#define O2_TCP_HUP (-9)
/// \brief an error return value indicating inet_pton() failed to convert a
/// string to an IP address
#define O2_HOSTNAME_TO_NETADDR_FAIL (-10)
/// an error return value: attempt to make a TCP connection failed
#define O2_TCP_CONNECT_FAIL (-11)
/// \brief an error return value: message was not scheduled or delivered
/// because the current time is not available
#define O2_NO_CLOCK (-12)
/// an error return value: no handler for an address
#define O2_NO_HANDLER (-13)
/// an error return value: an O2 message is invalid
#define O2_INVALID_MSG (-14)
/// an error return value: could not write to socket or send datagram
#define O2_SEND_FAIL (-15)
/// an error return value: a service name was NULL or contained a slash (/)
#define O2_BAD_SERVICE_NAME (-16)
/// an error return value: attempt to create a local service when one exists already
#define O2_SERVICE_EXISTS (-17)
/// an error return value: O2 has not been initialized
#define O2_NOT_INITIALIZED (-18)
// Status return codes for o2_status function:
/// \brief return value for o2_status(): local service, no clock sync yet
///
/// This is a local service
/// but clock sync has not yet been established so messages with non-zero
/// timestamps will be dropped.
#define O2_LOCAL_NOTIME 0
/// \brief return value for o2_status(): remote service but no clock sync yet
///
/// This is a remote service but clock sync has not yet been established so
/// messages with non-zero timestamps will be dropped. The remote service
/// may represent a bridge to a non-IP destination or to an OSC
/// server.
#define O2_REMOTE_NOTIME 1
/// \brief return value for o2_status(): service is connected but no
/// clock sync yet.
///
/// The service is attached to this process by a non-IP link. Clock sync
/// has not yet been established between the master clock and this
/// process, so non-zero timestamped messages to this service will be
/// dropped. Note that within other processes,
/// the status for this service will be #O2_REMOTE_NOTIME rather than
/// #O2_BRIDGE_NOTIME. Note also that O2 does not require the
/// remote bridged process to have a synchronized clock, so "NOTIME" only
/// means that *this* process is not synchronized and therefore cannot
/// (and will not) schedule a timestamped message for timed delivery.
#define O2_BRIDGE_NOTIME 2
/// \brief return value for o2_status(): service is connected but no
/// clock sync yet.
///
/// The service is local and forwards messages to an OSC server. The status
/// of the OSC server is not reported by O2 (and in the typical UDP case,
/// there is no way to determine if the OSC server is operational, so
/// "connected" may just mean that the service has been defined).
/// Clock sync has not yet been established between the master clock
/// and this process, so messages with non-zero timestamps to this service
/// will be dropped. Note that within other processes,
/// the status for this service will be #O2_REMOTE_NOTIME rather than
/// #O2_TO_OSC_NOTIME. Note also that O2 does not require the
/// OSC server to have a synchronized clock, so "NOTIME" only
/// means that *this* process is not synchronized to O2 and therefore cannot
/// (and will not) schedule a timestamped message for timed delivery.
#define O2_TO_OSC_NOTIME 3
/// \brief return value for o2_status(): local service with clock sync.
///
/// Note that even though the
/// service is local to the process and therefore shares a local
/// clock, clocks are not considered to be synchronized until the
/// local clock is synchronized to the master clock. If this process
/// provides the master clock, it is considered to be synchronized
/// immediately.
#define O2_LOCAL 4
/// \brief return value for o2_status(): remote service with clock sync.
///
/// Messages with non-zero timestamps can be sent because
/// clock sync has been established.
#define O2_REMOTE 5
/// \brief return value for o2_status(): connected with clock sync.
///
/// The service is attached by a non-IP link, and this process is synchronized.
/// If the bridged process is also synchronized, timed messages are
/// sent immediately and dispatched according to the synchronized
/// clock; if the bridged process is *not* synchronized, timed
/// messages are scheduled locally and sent according to the
/// timestamp, resulting in some added network latency.
#define O2_BRIDGE 6
/// \brief return value for o2_status(): connected with clock sync.
///
/// The service forwards messages directly from the current process
/// to an OSC server, and the process is synchronized. The status of
/// the OSC server is not reported by O2 (and in the typical UDP case,
/// there is no way to determine if the OSC server is operational).
/// Non-bundle O2 messages will be scheduled locally and sent according
/// to the timestamp to avoid creating a timestamped bundle, but this
/// will result in some added network latency. O2 bundles will be
/// converted to OSC bundles with timestamps based on Unix gettimeofday()
/// or Windows GetSystemTimeAsFileTime() which are then converted to
/// OSC-compatible NTP timestamps (this is all based on liblo; timestamped
/// message to liblo implementations of OSC will be correctly interpreted).
/// The resulting OSC bundles are sent immediately.
#define O2_TO_OSC 7
/** @} */
// Macros for o2 protocol
/* an internal value, ignored in transmission but check against O2_MARKER in the
* argument list. Used to do primitive bounds checking */
#define O2_MARKER_A (void *) 0xdeadbeefdeadbeefL
#define O2_MARKER_B (void *) 0xf00baa23f00baa23L
//#endif
extern void *((*o2_malloc)(size_t size));
extern void ((*o2_free)(void *));
void *o2_calloc(size_t n, size_t s);
/** \defgroup basics Basics
* @{
*/
#ifndef O2_NO_DEBUG
void *o2_dbg_malloc(size_t size, char *file, int line);
void o2_dbg_free(void *obj, char *file, int line);
#define O2_MALLOC(x) o2_dbg_malloc(x, __FILE__, __LINE__)
#define O2_FREE(x) o2_dbg_free(x, __FILE__, __LINE__)
#endif
/** \brief allocate memory
*
* O2 allows you to provide custom heap implementations to avoid
* priority inversion or other real-time problems. Normally, you
* should not need to explicitly allocate memory since O2 functions
* are provided to allocate, construct, and deallocate messages, but
* if you need to allocate memory, especially in an O2 message
* handler callback, i.e. within the sphere of O2 execution, you
* should use #O2_MALLOC, #O2_FREE, and #O2_CALLOC.
*/
#ifndef O2_MALLOC
#ifdef NO_O2_DEBUG
#define O2_MALLOC(x) (*o2_malloc)(x)
#else
#define O2_MALLOC(x) o2_dbg_malloc(x, __FILE__, __LINE__)
#endif
#endif
/** \brief free memory allocated by #O2_MALLOC */
#ifndef O2_FREE
#ifdef NO_O2_DEBUG
#define O2_FREE(x) (*o2_free)(x)
#else
#define O2_FREE(x) (*o2_dbg_free)(x, __FILE__, __LINE__)
#endif
#endif
/** \brief allocate and zero memory (see #O2_MALLOC) */
#ifndef O2_CALLOC
#ifdef NO_O2_DEBUG
void *o2_calloc(size_t n, size_t s);
#define O2_CALLOC(n, s) o2_calloc((n), (s))
#else
void *o2_dbg_calloc(size_t n, size_t s, char *file, int line);
#define O2_CALLOC(n, s) o2_dbg_calloc((n), (s), __FILE__, __LINE__)
#endif
#endif
/** \brief O2 timestamps are doubles representing seconds since the
* approximate start time of the application.
*/
typedef double o2_time;
/** \brief data part of an O2 message
*
* This data type is used to pass o2 message data to message handlers.
* It appears many other times in the code. You should NEVER allocate
* or free an o2_msg_data struct. Instead, create a message using
* o2_send_start(), o2_add_*(), and o2_message_finish() to get an
* o2_message_ptr. Within the o2_message, the data field is an
* o2_msg_data structure. We would use o2_message everywhere instead
* of o2_msg_data, but bundles can contain multiple o2_msg_data
* structures without the extra baggage contained in an o2_message.
*
* Note: it is assumed that an o2_msg_data struct is always preceded
* by a 32-bit length. Ideally, length should therefore be in this
* struct, but then the compiler might add padding to put the timestamp
* on an 8-byte alignment. This could be solved with a pack pragma, but
* that is not standard C. To be safe and portable, I decided to just
* leave length out of the struct. The macro MSG_DATA_LENGTH can be used
* to access the length field.
*/
typedef struct o2_msg_data {
o2_time timestamp; ///< the message delivery time (0 for immediate)
/** \brief the message address string
*
* Although this field is declared as 4 bytes, actual messages
* have variable length, and the address is followed by a
* string of type codes and the actual parameters. The length
* of the entire message including the timestamp is given by
* the `length` field.
*/
char address[4];
} o2_msg_data, *o2_msg_data_ptr;
// get the length from a pointer to an o2_msg_data. This macro dereferences
// the o2_msg_data pointer to impose some mild typechecking. Not just any
// pointer will work.
#define MSG_DATA_LENGTH(m) (((int32_t *) &((m)->timestamp))[-1])
/** \brief get the type string from o2_msg_data_ptr
*
* Type strings begin with the comma (",") character, which is skipped
*/
#define WORD_ALIGN_PTR(p) ((char *) (((size_t) (p)) & ~3))
#define O2_MSG_TYPES(msg) \
WORD_ALIGN_PTR((msg)->address + strlen((msg)->address) + 4) + 1;
/** \brief an O2 message container
*
* Note: This struct represents an O2 message that is stored on the heap.
* The length field must preceded data with no padding (see o2_msg_data
* declaration and the note that precedes it). To make sure there is no
* padding between length and data, we force the next pointer to occupy
* 8 bytes even if this is a 32-bit machine by making it part of a union
* with an 8-byte int64_t field named "pad_if_needed."
*
* Note that o2_messages are on the heap and can be allocated, scheduled,
* sent, and freed. In contrast, o2_msg_data structures are contained
* within o2_messages and are passed to method handlers, but cannot be
* allocated, scheduled, sent, or freed. They are always the data field
* of a containing o2_message.
*/
typedef struct o2_message {
union {
struct o2_message *next; ///< links used for free list and scheduler
int64_t pad_if_needed; ///< make sure allocated is 8-byte aligned
};
union {
int tcp_flag; ///< send message by tcp?
int64_t pad_if_needed2; ///< make sure allocated is 8-byte aligned
};
int32_t allocated; ///< how many bytes allocated in data part
int32_t length; ///< the length of the message in data part
o2_msg_data data;
} o2_message, *o2_message_ptr;
/**
* \brief The structure for binary large object.
*
* A blob can be passed in an O2 message using the 'b' type. Created
* by calls to o2_blob_new().
*/
typedef struct o2_blob {
uint32_t size; ///< size of data
char data[4]; ///< the data, actually of variable length
} o2_blob, *o2_blob_ptr;
/**
* \brief An enumeration of the O2 message types.
*/
typedef enum {
// basic O2 types
O2_INT32 = 'i', ///< 32 bit signed integer.
O2_FLOAT = 'f', ///< 32 bit IEEE-754 float.
O2_STRING = 's', ///< NULL terminated string (Standard C).
O2_BLOB = 'b', ///< Binary Large OBject (BLOB) type.
O2_ARRAY_START = '[', ///< Start array or tuple
O2_ARRAY_END = ']', ///< End array or tuple
// extended O2 types
O2_INT64 = 'h', ///< 64 bit signed integer.
O2_TIME = 't', ///< OSC time type.
O2_DOUBLE = 'd', ///< 64 bit IEEE-754 double.
O2_SYMBOL = 'S', ///< Used in systems distinguish strings and symbols.
O2_CHAR = 'c', ///< 8bit char variable (Standard C).
O2_MIDI = 'm', ///< 4 byte MIDI packet.
O2_TRUE = 'T', ///< Symbol representing the value True.
O2_FALSE = 'F', ///< Symbol representing the value False.
O2_NIL = 'N', ///< Symbol representing the value Nil.
O2_INFINITUM = 'I', ///< Symbol representing the value Infinitum.
// O2 types
O2_BOOL = 'B', ///< Boolean value returned as either 0 or 1
O2_VECTOR = 'v', ///< Prefix to indicate a vector
} o2_type, *o2_type_ptr;
/**
* \brief union of all O2 parameter types
*
* An o2_arg_ptr is a pointer to an O2 message argument. If argument
* parsing is requested (by setting the parse parameter in o2_method_new),
* then the handler receives an array of o2_arg_ptrs. If argument parsing
* is not requested, you have the option of parsing the message one
* parameter at a time by calling o2_get_next(), which returns an
* o2_arg_ptr.
*
* The o2_arg_ptr can then be dereferenced to obtain a value of the
* expected type. For example, you could write
* \code{.c}
* double d = o2_get_next()->d;
* \endcode
* to extract a parameter of type double. (This assumes that the message
* is properly formed and the type string indicates that this parameter is
* a double, or that type coercion was enabled by the coerce flag in
* o2_method_new().)
*/
typedef union {
int32_t i32; ///< 32 bit signed integer.
int32_t i; ///< an alias for i32
int64_t i64; ///< 64 bit signed integer.
int64_t h; ///< an alias for i64
float f; ///< 32 bit IEEE-754 float.
float f32; ///< an alias for f
double d; ///< 64 bit IEEE-754 double.
double f64; ///< an alias for d
char s[4]; ///< Standard C, NULL terminated string.
/** \brief Standard C, NULL terminated, string.
Used in systems which distinguish strings and symbols. */
char S[4];
int c; ///< Standard C, 8 bit, char, stored as int.
uint32_t m; ///< A 4 byte MIDI packet. MSB to LSB are port id,
///< status, data1, data2
o2_time t; ///< TimeTag value.
o2_blob b; ///< a blob (unstructured bytes)
int32_t B; ///< a boolean value, either 0 or 1
struct {
int32_t len; ///< length of vector in bytes
///< IMPORTANT: divide by 4 or 8 to get length in elements
int32_t typ; ///< type of vector elements
union {
int32_t *vi; ///< vector of 32-bit signed integers
int64_t *vh; ///< vector of 64-bit signed integers
double *vd; ///< vector of IEEE-754 doubles
float *vf; ///< vector of IEEE-754 floats
// note that a blob is basically a vector of bytes;
// there is no type conversion from blob to vector though,
// and no vector of shorts or bytes because if you converted
// to a vector of int64_t, it would take 8x the message
// space, forcing us to allocate very big buffers to
// unpack messages.
};
} v;
} o2_arg, *o2_arg_ptr;
extern o2_arg_ptr o2_got_start_array;
extern o2_arg_ptr o2_got_end_array;
/** \brief name of the application
*
* A collection of cooperating O2 processes forms an
* *application*. Applications must have unique names. This allows
* more than one application to exist within a single network without
* conflict. For example, there could be two applications, "joe" and
* "sue", each with services named "synth." Since the application
* names are different, joe's messages to the synth service go to
* joe's synth and not to sue's synth.
*
* Do not set, modify or free this variable! Consider it to be
* read-only. It is managed by O2 using o2_initialize() and o2_finish().
*/
extern const char *o2_application_name;
/** \brief set this flag to stop o2_run()
*
* Some O2 applications will initialize and call o2_run(), which is a
* simple loop that calls o2_poll(). To exit the loop, set
* #o2_stop_flag to #TRUE
*/
extern int o2_stop_flag;
/**
* \brief callback function to receive an O2 message
*
* @param msg The full message in host byte order.
* @param types If you set a type string in your method creation call,
* then this type string is provided here. If you did not
* specify a string, types will be the type string from the
* message (without the initial ','). If parse_args and
* coerce_flag were set in the method creation call,
* types will match the types in argv, but not necessarily
* the type string or types in msg.
* @param argv An array of #o2_arg types containing the values, e.g. if the
* first argument of the incoming message is of type 'f' then
* the value will be found in argv[0]->f. (If parse_args was
* not set in the method creation call, argv will be NULL.)
* For vectors, specified in types by the sequence "vi", "vh",
* "vf", or "vd", there will be one pointer in argv pointing to
* a vector description (the v field in o2_arg). For arrays,
* there are *no* pointers corresponding to '[' or ']' in the
* types string; but there is one pointer in argv for each array
* element.
* @param argc The number of arguments received. (This is valid even if
* parse_args was not set in the method creation call.) This is
* the length of argv. Vectors count as one, array elements count
* as one each, and arrays themselves are not represented. For
* example, an empty array ("[]") in the type string adds
* nothing to the argc count or argv vector.
* @param user_data This contains the user_data value passed in the call
* to the method creation call.
*/
typedef void (*o2_method_handler)(const o2_msg_data_ptr msg, const char *types,
o2_arg_ptr *argv, int argc, void *user_data);
/**
* \brief Start O2.
*
* If O2 has not been initialized, it is created and intialized.
* O2 will begin to establish connections to other instances
* with a matching application name.
*
* @param application_name the name of the application. O2 will attempt to
* discover other processes with a matching application name,
* ignoring all processes with non-matching names.
*
* @return #O2_SUCCESS if success, #O2_FAIL if an error occurs,
* #O2_RUNNING if already running, #O2_BAD_NAME if `application_name`
* is NULL.
*/
int o2_initialize(const char *application_name);
/**
* \brief Tell O2 how to allocate/free memory.
*
* In many C library implementations, the standard implementation of
* free() must lock a data structure. This can lead to priority
* inversion if O2 runs at an elevated priority. Furthermore, the
* standard `malloc()` and `free()` do not run in constant (real) time. To
* avoid these problems, you can provide an alternate heap
* implementation for O2 by calling this function before calling
* o2_initialize(). For example, the provided functions can implement
* a private heap for the thread running O2.
*
* @param malloc a function pointer that behaves like standard
* `malloc()`
* @param free a function pointer that behaves like standard `free()`
*
* @return O2_SUCCESS if succeed, O2_FAIL if not.
*/
int o2_memory(void *((*malloc)(size_t size)), void ((*free)(void *)));
/**
* \brief Set discovery period
*
* O2 discovery messages are broadcast periodically in case a new process
* has joined the application. The default period is 4 seconds. If there
* are N processes, each host will receive N/4 discovery messages per
* second. Since there are 5 discovery ports, each process will handle
* N/20 discovery messages per second, and a discovery message from any
* given process will be received every 20 seconds. (Note, however, that
* new processes send more frequently, sending 2 discovery messages to
* each of the 5 discovery port numbers within 2 seconds, so if messages
* are not dropped frequently, discovery of new processes will happen much
* faster than the worst-case 20 second polling period or even the
* 10 second expected wait.)
*
* You can change the polling period from 4s by calling this function. The
* new polling period takes effect when the next discovery message is sent
* at the end of the current polling period.
*
* @param period the requested polling period; a minimum of 0.1s is enforced;
* 4s is the default (recommended).
*
* @return the previous polling period
*/
o2_time o2_set_discovery_period(o2_time period);
/**
* \brief Add a service to the current application.
*
* Once created, services are "advertised" to other processes with
* matching application names, and messages are delivered
* accordingly. E.g. to handle messages addressed to "/synth/volume"
* you call
* \code{.c}
* o2_service_new("synth");
* o2_method_new("/synth/volume", "f", synth_volume_handler, NULL, NULL, TRUE);
* \endcode
* and define `synth_volume_handler` (see the type declaration for
* #o2_method_handler and o2_method_new())
* Normally, services should be *unique* across the application. If
* #service_name is already locally defined in this process (by a previous
* call to #o2_service_new or #o2_osc_delegate), this call will fail,
* returning #O2_SERVICE_EXISTS. If matching service names are defined
* in two different processes, the process with the highest IP and port
* number (lexicographically) will provide the service. However, due to
* the distributed and asynchronous nature of O2, there may be some
* intervening time (typically a fraction of a second) during which a
* service is handled by two different processes. Furthermore, the switch
* to a new service provider could redirect a stream of messages, causing
* unexpected behavior in the application.
*
* @param service_name the name of the service
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
int o2_service_new(const char *service_name);
/**
* \brief Remove a local service
*
* The #service_name corresponds to the parameter previously passed to
* #o2_service_new or #o2_osc_delegate. Note that if an OSC port
* forwards to this service (see #o2_osc_port_new), the port remains
* open, but the OSC messages will be dropped. See #o2_osc_port_free().
*
* @param service_name the name of the service
*
* @return #O2_SUCCSS if success, #O2_FAIL if not.
*/
int o2_service_free(char *service_name);
/**
* \brief Add a handler for an address.
*
* @param path the address including the service name. If the address
* is only the service name with no trailing slash,
* the handler will match any message to the service.
* Addresses should not conflict: An address should
* not match another address, and for every pair of
* addresses X and Y, X/ should not be a prefix of Y.
* @param typespec the types of parameters, use "" for no parameters and
* NULL for no type checking
* @param h the handler
* @param user_data pointer saved and passed to handler
* @param coerce is true if you want to allow automatic coercion of types.
* Coercion is only enabled if both coerce and parse are
* true.
* @param parse is true if you want O2 to construct an argv argument
* vector to pass to the handle
*
* @return O2_SUCCESS if succeed, O2_FAIL if not.
*/
int o2_method_new(const char *path, const char *typespec,
o2_method_handler h, void *user_data, int coerce, int parse);
/**
* \brief Process current O2 messages.
*
* Since O2 does not create a thread and O2 requires active processing
* to establish and maintain connections, the O2 programmer (user)
* should call o2_poll() periodically, even if not offering a service.
* o2_poll() runs a discovery protocol to find and connect to other
* processes, runs a clock synchronization protocol to establish valid
* time stamps, and handles incoming messages to all services. O2_poll()
* should be called at least 10 times per second. Messages can only be
* delivered during a call to o2_poll() so more frequent calls will
* generally lower the message latency as well as the accuracy of the
* clock synchronization (at the cost of greater CPU utilization).
* Human perception of timing jitter is on the order of 10ms, so
* polling rates of 200 to 1000 are advised in situations where
* rhythmic accuracy is expected.
*
* @return 0 (O2_SUCCESS) if succeed, -1 (O2_FAIL) if not.
*/
int o2_poll();
/**
* \brief Run O2.
*
* Call o2_poll() at the rate (in Hz) indicated.
* Returns if a handler sets #o2_stop_flag to non-zero.
*/
int o2_run(int rate);
/**
* \brief Check the status of the service.
*
* @param service the name of the service
* @return
* - #O2_FAIL if no service is found,
* - #O2_LOCAL_NOTIME if the service is local but we have no clock sync yet,
* - #O2_REMOTE_NOTIME if the service is remote but we have no clock sync yet,
* - #O2_BRIDGE_NOTIME if service is attached by a non-IP link, but we have
* no clock sync yet (if the non-IP connection is not handled
* by this process, the service status will be #O2_REMOTE_NOTIME),
* - #O2_TO_OSC_NOTIME if service forwards to an OSC server but we
* have no clock sync yet (if the OSC connection is not handled
* by this process, the service status will be #O2_REMOTE_NOTIME),
* - #O2_LOCAL if service is local and we have clock sync,
* - #O2_REMOTE if service is remote and we have clock sync,
* - #O2_BRIDGE if service is handled locally by forwarding to an
* attached non-IP link, and we have clock sync. (If the non-IP
* connection is not local, the service status will be #O2_REMOTE).
* - #O2_TO_OSC if service is handled locally by forwarding to an OSC
* server and this process has clock sync. (If the OSC
* connection is not handled locally, the service status will be
* #O2_REMOTE).
*
* @return Note that codes are carefully
* ordered to allow testing for categories:
* - to test if delivery is possible with a zero (immediate) timestamp,
* use `o2_status(service) > O2_FAIL`, `o2_status(service) >= 0`, or
* `o2_status(service) >= O2_LOCAL_NOTIME`.
* - to test if delivery is possible with a non-zero timestamp, use
* `o2_status(service) >= O2_LOCAL`. Note that status can change over
* time, e.g. the
* status of a remote service will be #O2_FAIL until the service is
* discovered. It will then change to #O2_REMOTE_NOTIME until both the
* sender and receiver achieve clock synchronization and share their
* synchronized status, and finally the status will become #O2_REMOTE.
*
* In the cases with no clock sync, it is safe to send an immediate message
* with timestamp = 0, but non-zero timestamps are meaningless because
* either the sending process has no way to obtain a valid timestamp
* or the receiver has no way to schedule delivery according to a
* timestamp.
*
* Messages to services are *dropped* if the service has not been
* discovered. Timestamped messages (timestamp != 0) are *dropped* if
* the sender and receiver are not
* clock-synchronized. (`o2_status(service) >= O2_LOCAL`).
*
* A special case is with `BRIDGE` and `OSC` services. In these cases,
* the O2 process offering the service can either schedule the
* messages locally, sending them according to the timestamp (and
* suffering some network latency), or if the destination process is
* synchronized, messages can be forwarded immediately for more
* precise scheduling at their final destination. O2 does not provide
* any way for clients/users to determine which of these methods is in
* effect, and in the case of messages being forwarded by an
* intermediary O2 process, the originator of the message cannot
* determine whether the service is offered by an O2 server on the
* local network, by an OSC server, or through a bridge to another
* network such as Bluetooth. The status at the originator will be
* simply #O2_REMOTE or #O2_REMOTE_NOTIME.
*/
int o2_status(const char *service);
/**
* \brief A variable indicating that the clock is the master or is
* synchronized to the master.
*/
extern int o2_clock_is_synchronized;
/**
* \brief Get network round-trip information.
*
* @return If clock is synchronized, return O2_SUCCESS and set
* `*mean` to the mean round-trip time and `*min` to the minimum
* round-trip time of the last 5 (where 5 is the value of
* CLOCK_SYNC_HISTORY_LEN) clock sync requests. Otherwise,
* O2_FAIL is returned and `*mean` and `*min` are unaltered.
*/
int o2_roundtrip(double *mean, double *min);
/** \brief signature for callback that defines the master clock
*
* See o2_clock_set() for details.
*/
typedef o2_time (*o2_time_callback)(void *rock);
/**
* \brief Provide a time reference to O2.
*
* Exactly one process per O2 application should provide a master
* clock. All other processes synchronize to the master. To become
* the master, call o2_clock_set().
*
* The time reported by the gettime function will be offset to
* match the current local time so that local time continues to
* increase smoothly. You cannot force O2 time to match an external
* absolute time, but once o2_clock_set() is called, the difference
* between the time reference and O2's local time (as reported by
* o2_local_time()) will be fixed.
*
* @param gettime function to get the time in units of seconds. The
* reference may be operating system time, audio system time, MIDI
* system time, or any other time source. The times returned by this
* function must be non-decreasing and must increase by one second
* per second of real time to close approximation. The value may be
* NULL, in which case a default time reference will be used.
*
* @parm rock an arbitrary value that is passed to the gettime
* function. This may be need to provide context. Use NULL if no
* context is required.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
int o2_clock_set(o2_time_callback gettime, void *rock);
/**
* \brief Construct and send O2 message with best effort protocol
*
* Normally, this constructs and sends an O2 message via UDP. If the
* destination service is reached via some other network protocol
* (e.g. Bluetooth), the message is delivered in the lowest latency
* protocol available, with no guaranteed delivery.
*
* @param path an address pattern
* @param time when to dispatch the message, 0 means right now. In any
* case, the message is sent to the receiving service as soon as
* possible. If the message arrives early, it will be held at the
* service and dispatched as soon as possible after the indicated time.
* @param typestring the type string for the message. Each character
* indicates one data item. Type codes are as in OSC.
* @param ... the data of the message. There is one parameter for each
* character in the typestring.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*
*/
/** \hideinitializer */ // turn off Doxygen report on o2_send_marker()
#define o2_send(path, time, ...) \
o2_send_marker(path, time, FALSE, \
__VA_ARGS__, O2_MARKER_A, O2_MARKER_B)
/** \cond INTERNAL */ \
int o2_send_marker(const char *path, double time, int tcp_flag,
const char *typestring, ...);
/** \endcond */
/**
* \brief Construct and send an O2 message reliably.
*
* Normally, this constructs and sends an O2 message via TCP. If the
* destination service is reached via some other network protocol
* (e.g. Bluetooth), the message is delivered using the most reliable
* protocol available. (Thus, this call is considered a "hint" rather
* than an absolute requirement.)
*
* @param path an address pattern
* @param time when to dispatch the message, 0 means right now. In any
* case, the message is sent to the receiving service as soon as
* possible. If the message arrives early, it will be held at the
* service and dispatched as soon as possible after the indicated time.
* @param typestring the type string for the message. Each character
* indicates one data item. Type codes are defined by #o2_type.
* @param ... the data of the message. There is one parameter for each
* character in the typestring.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
/** \hideinitializer */ // turn off Doxygen report on o2_send_marker()
#define o2_send_cmd(path, time, ...) \
o2_send_marker(path, time, TRUE, \
__VA_ARGS__, O2_MARKER_A, O2_MARKER_B)
/**
* \brief Send an O2 message. (See also macros #o2_send and #o2_send_cmd).
*
* @param msg points to an O2 message.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*
* After the call, the `msg` parameter is "owned" by O2, which will
* free it. Therefore, do *not* free msg after calling o2_message_send().
*/
int o2_message_send(o2_message_ptr msg);
/**
* \brief Get the estimated synchronized global O2 time.
*
* This function returns a valid value either after you call
* o2_clock_set(), making the local clock the master clock for the O2
* application, or after O2 has finished discovering and
* synchronizing with the master clock. Until then, -1 is returned.
*
* The clock accuracy depends upon network latency, how often
* o2_poll() is called, and other factors, but
*
* @return the time in seconds, or -1 if global (master) time is unknown.
*/
o2_time o2_time_get();
/**
* \brief Get the real time using the local O2 clock
*
* @return the local time in seconds
*/
o2_time o2_local_time();
/**
* \brief Return text representation of an O2 error
*
* @param i error number returned from some O2 function
*
* @return return the error message as a string
*/
const char *o2_error_to_string(int i);
/**
* \brief release the memory and shut down O2.
*
* Close all sockets, free all memory, and restore critical
* variables so that O2 behaves as if it was never initialized.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
int o2_finish();
// Interoperate with OSC
/**
* \brief Create a port to receive OSC messages.
*
* OSC messages are converted to O2 messages and directed to the service.
* E.g. if the service is "maxmsp" and the message address is
* `/foo/x`, then the message is directed to and handled by
* `/maxmsp/foo/x`. If the #service_name does not exist at any time
* after calling #o2_osc_port_new, incoming OSC messages will be dropped
* until the service is available again.
*
* @param service_name The name of the service to which messages are delivered
* @param port_num Port number.
* @param tcp_flag Be a TCP server for remote clients. Otherwise, use UDP
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
int o2_osc_port_new(const char *service_name, int port_num, int tcp_flag);
/**
* \brief Remove a port receiving OSC messages.
*
* This removes a port created by #o2_osc_port_new(). If you want to
* remove the corresponding service, you must also call #o2_service_free()
* with the service name.
*
* @param port_num The port number that receives OSC messages.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*
*/
int o2_osc_port_free(int port_num);
/**
* \brief Create a service that forwards O2 messages to an OSC server.
*
* @param service_name The o2 service name without a '/' prefix.
* @param ip The ip address of the osc server.
* @param port_num The port number of the osc server.
* @param tcp_flag Send OSC message via TCP protocol, in which case
* port_num is the TCP server port, not a connection.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*
* If `tcp_flag` is set, a TCP connection will be established with
* the OSC server.
* When the created service receives any O2 messages, it will
* send the message to the OSC server. If the incoming message has
* a timestamp for some future time, the message will be held until
* that time, then sent to the OSC server. (Ideally, O2 could convert
* the message to an OSC timestamped bundle and send it immediately
* to achieve precise forward-synchronous timing, but this requires
* clock synchronization with the OSC server, which is normally
* unimplemented.)
*
* If this is a tcp connection, close it by calling #o2_service_free().
*/
int o2_osc_delegate(const char *service_name, const char *ip, int port_num,
int tcp_flag);
/**
* \brief Set the OSC time offset.
*
* @param offset the offset between (global) O2 time and OSC time
*
* @return the previous offset
*
* O2 global time should start from 0.0 when the clock is started, whereas
* OSC time starts at 1 Jan 1900. The offset is the OSC time corresponding
* to O2 time 0.0. Equivalently, OSC_time = O2_time + offset.
*/
uint64_t o2_osc_time_offset(uint64_t offset);
/** @} */ // end of Basics
/**
* \defgroup lowlevelsend Low-Level Message Send
*
* Rather than passing all parameters in one call or letting O2
* extract parameters from a message before calling its handler,
* these functions allow building messages one parameter at a time
* and extracting message parameters one at a time.
* The functions operate on "hidden" messages, so these functions are
* not reentrant.
*
* To build a message, begin by calling o2_send_start() to allocate a
* message. Then call one of the `o2_add_()` functions to add each
* parameter. Finally, call either o2_send_finish() to send the
* message. You should not explicitly allocate or deallocate a
* message using this procedure.
*
* To extract parameters from a message, begin by calling
* o2_extract_start() to prepare to get parameters from the
* message. Then call o2_get_next() to get each parameter. If the
* result is non-null, a parameter of the requested type was obtained
* and you can read the parameter from the result. Results other than
* strings, MIDI, and blobs may only remain valid until the next call
* to o2_get_next(), so you should use or copy the value before reading
* the next one. Values that are not coerced (requiring a copy) are
* left in the O2 message and have the same lifetime as the message.
* You should not reuse this storage because the message may have
* multiple destinations; thus, the message content should not be altered.
*
* A by-product of o2_extract_start() and o2_get_next() is an argument
* vector (argv) that can be accessed from o2_argv. (This is the same
* argument vector created automatically when a handler is added with
* o2_method_new() when the parse parameter is true.) A possible
* advantage of using a sequence of o2_get_next() calls rather than
* simply setting the parse flag is that you can receive messages with
* various types and numbers of parameters. Also, you can check vector
* lengths and stop parsing if unacceptable lengths are encountered.
*
* o2_get_next() will perform type conversion if possible
* when the requested type does not match the actual type. You can
* determine the original type by reading the type string in the
* message. The number of parameters is determined by the length of
* the type string, with some exceptions.
*
* Vectors can be coerced into arrays, in which case
* each element will be coerced as requested. Arrays can be coerced
* into vectors if each element of the array can be coerced into
* the expected vector element type. Vector lengths are provided by
* the message; there is no way to coerce or limit vector lengths or
* check that the length matches an expected value. (You can determine
* the length from the return value and of course you can decide to
* reject the message if the length is not acceptable.)
*
* When a vector is returned, the argument vector has a single element
* that points to a vector descriptor (the "v" field), which contains
* the vector element types and the length of the vector (>= 0).
*
* When an array is returned, the argument vector contains the value
* o2_got_start_array followed by an o2_arg_ptr for each element of
* the array, followed by o2_got_end_array.
*
* When types T (True), F (False), I (Infinitum), or N (Nil) are in
* the message, there is an entry in the argument vector; however,
* there is no data associated with these types (other than the type
* itself), so the pointers point to zero bytes and therefore should
* not be used.
*
* In all other cases, the argument vector contains data
* corresponding to the data item in the message. This may be a pointer
* into the actual message or a pointer to a temporary location in case
* the element was coerced to a different type.
*
* When the actual type code in the message is in "TFIN" you should
* call o2_get_next() even though there is no corresponding data
* stored in the message. The return value, if successful, is a
* non-NULL pointer that points within or just after the message, but
* you must not dereference this pointer. (NULL indicates failure as
* with other type codes. One rationale for calling o2_get_next()
* even when there is nothing to "get" is that you can call
* o2_get_next('B') to retrieve 'T', 'F', or 'B' types as an int32_t
* which is 0 or 1. The 'I' and 'N' types are never coerced.
*
* Normally, you should not free the message because
* normally you are accessing the message in a handler and the message
* will be freed by the O2 message dispatch code that called the
* handler.
*
* Arrays denoted by [...] in the type string are handled in a somewhat
* special way:
*
* If an array is expected, call o2_get_next('['). The return value will be
* o2_got_start_array on success, or NULL if there is no array. The actual
* value in the message may be an array or a vector. If it is a vector, the
* elements of the vector will be coerced to the types requested in
* successive calls to o2_get_next(). After retrieving array elements, call
* o2_get_next(']'). The return value should be o2_got_end_array. NULL is
* returned if there is an error. For example, suppose you call o2_get_next()
* with characters from the type string "[id]" and the actual parameter is
* a vector integers ("vi") of length 2. The return values from o2_get_next()
* will be o2_got_start_array, an o2_arg_ptr to an integer, an o2_arg_ptr to
* a double (coerced from the integer vector), and finally o2_got_end_array.
* If the vector length is 1, the third return value will be NULL. If the
* vector length is 3 (or more), the fourth return value will be NULL rather
* than o2_got_end_array.
*
* The special values o2_got_start_array and o2_got_end_array are not valid
* structures. In other words, fields such as o2_got_start_array->i32 are
* never valid or meaningful. Instead, o2_got_start_array and o2_got_end_array
* are just 'tokens' used to indicate success in type checking. These values
* are distinct from NULL, which indicates a type incompatibility.
*
* Note also that vector elements cannot be retrieved directly without
* calling o2_get_next('v') or o2_get_next('['). For example, if the actual
* argument is a two-element integer vector ("vi"), a call to
* o2_get_next(O2_INT32) will fail unless it is preceded by
* o2_get_next(O2_VECTOR) or o2_get_next(O2_ARRAY_START).
*
* If a vector is expected, call o2_get_next(O2_VECTOR). The return value will
* be a non-null o2_arg_ptr if the next argument in the actual message
* is a vector or array, and otherwise NULL. You should not dereference this
* return value yet...
*
* You *must* then call o2_get_next() with the desired type for vector
* elements. The return value will be an o2_arg_ptr (which will be
* the same value previously returned) containing v.typ set to
* the desired type, v.len still set to the number of elements, and v.vi,
* v.vh, v.vd, v.vf, or v.vc pointing to the possibly coerced elements.
*
* Note that the sequence of calling o2_get_next() twice for vectors
* corresponds to the two type characters used to encode them, e.g. "vi"
* indicates a vector of integers.
*
* Coercion is supported as follows. If coercion is provided from
* the type indicated on the left on some row to the types corresponding
* to columns where an "x" appears ("*" indicates special consideration
* described below.
*
* i h f d t s S T F B b m c N I
* i x x x x x * * x 32-bit int
* h x x x x x * * x 64-bit int
* f x x x x x * * x float
* d x x x x x * * x double
* t x x x x x time
* s x x String
* S x x Symbol
* T x x x x x x True
* F x x x x x x False
* B x x x x * * x Boolean
* b x blob
* m x MIDI
* c x character
* N x Nil
* I x Infinitum
*
* *Entries marked with "*": Coercion succeeds
* from 0 to False and from non-zero to True,
* otherwise coercion fails.
*/
/** \addtogroup lowlevelsend
* @{
*/
/**
* \brief Allocate a blob.
*
* Allocate a blob and initialize the size field. If the return address
* is not NULL, copy data (up to length size) to `blob->data`. You can
* change `blob->size`, but of course you should not set `blob->size`
* greater than the `size` parameter originally passed to o2_blob_new().
*
* Caller is responsible for freeing the returned blob using O2_FREE().
*
* A constructed blob can be added to a message. If you add parameters to
* a message one-at-a-time, you can use o2_add_blob_data() to copy data
* directly to a message without first allocating a blob and copying
* data into it.
*
* @param size The size of the data to be added to the blob
*
* @return the address of the new blob or NULL if memory cannot be allocated.
*/
o2_blob_ptr o2_blob_new(uint32_t size);
/**
* \brief Prepare to build a message
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*
* Allocates a "hidden" message in preparation for adding
* parameters. After calling this, you should call `o2_add_` functions
* such as o2_add_int32() to add parameters. Then call
* o2_send_finish() to send the message.
*/
int o2_send_start();
/// \brief add a `float` to the message (see o2_send_start())
int o2_add_float(float f);
/// \brief This function suppports o2_add_symbol() and o2_add_string()
/// Normally, you should not call this directly.
int o2_add_string_or_symbol(o2_type tcode, const char *s);
/// \brief add a symbol to the message (see o2_send_start())
#define o2_add_symbol(s) o2_add_string_or_symbol(O2_SYMBOL, s)
/// \brief add a string to the message (see o2_send_start())
#define o2_add_string(s) o2_add_string_or_symbol(O2_STRING, s)
/// \brief add an `o2_blob` to the message (see o2_send_start()), where
/// the blob is given as a pointer to an #o2_blob object.
int o2_add_blob(o2_blob_ptr b);
/// \brief add an `o2_blob` to the message (see o2_send_start()), where
/// the blob is specified by a size and a data address.
int o2_add_blob_data(uint32_t size, void *data);
/// \brief add an `int64` to the message (see o2_send_start())
int o2_add_int64(int64_t i);
/// \brief This function supports o2_add_double() and o2_add_time()
/// Normally, you should not call this directly.
int o2_add_double_or_time(o2_type tchar, double d);
/// \brief add a `double` to the message (see o2_send_start())
#define o2_add_double(d) o2_add_double_or_time(O2_DOUBLE, d)
/// \brief add a time (`double`) to the message (see o2_send_start())
#define o2_add_time(t) o2_add_double_or_time(O2_TIME, t)
/// \brief This function supports o2_add_int32() and o2_add_char()
/// Normally, you should not call this directly.
int o2_add_int32_or_char(o2_type tcode, int32_t i);
/// \brief add an `int32` to the message (see o2_send_start())
#define o2_add_int32(i) o2_add_int32_or_char(O2_INT32, i)
/// \brief add a `char` to the message (see o2_send_start())
#define o2_add_char(c) o2_add_int32_or_char(O2_CHAR, c)
/// \brief add a short midi message to the message (see o2_send_start())
int o2_add_midi(uint32_t m);
/// \brief This function supports o2_add_true(), o2_add_false(), o2_add_bool(),
/// o2_add_nil(), o2_add_infinitum(), and others.
/// Normally, you should not call this directly.
int o2_add_only_typecode(o2_type typecode);
/// \brief add "true" to the message (see o2_send_start())
#define o2_add_true() o2_add_only_typecode(O2_TRUE);
/// \brief add a "false" to the message (see o2_send_start())
#define o2_add_false() o2_add_only_typecode(O2_FALSE);
/// \brief add 0 (false) or 1 (true) to the message (see o2_send_start())
#define o2_add_bool(x) o2_add_int32_or_char(O2_BOOL, x != 0)
/// \brief add "nil" to the message (see o2_send_start())
#define o2_add_nil() o2_add_only_typecode(O2_NIL);
/// \brief add "infinitum" to the message (see o2_send_start())
#define o2_add_infinitum() o2_add_only_typecode(O2_INFINITUM);
/// \brief start adding an array
#define o2_add_start_array() o2_add_only_typecode(O2_ARRAY_START);
/// \brief finish adding an array
#define o2_add_end_array() o2_add_only_typecode(O2_ARRAY_END);
/** \brief add a vector
*
* @param element_type the type of the vector elements
* @param length the number of vector elements
* @param data the vector elements; arranged sequentially in memory
* in a format determined by element_type. The element
* type is restricted to a character in "ifhtdc"
*/
int o2_add_vector(o2_type element_type,
int length, void *data);
/**
* \brief add a message to a bundle
*
* @param msg a message or bundle to add
*
* @return O2_SUCCESS
*
* This function can be called after o2_send_start(). If you
* add a message to a bundle with this function, you must not
* call any other o2_add_*() functions. E.g. do not call both
* o2_add_int32() and o2_add_message() on the same message.
*
* This function does NOT free msg. Probably you should call
* o2_message_free(msg) after calling o2_add_message(msg).
*/
int o2_add_message(o2_message_ptr msg);
/**
* \brief finish and return the message.
*
* @param time the timestamp for the message (0 for immediate)
* @param address the O2 address pattern for the message
* @param tcp_flag boolean if true, send message reliably
*
* @return the address of the completed message, or NULL on error
*
* The message must be freed using o2_message_free() or by calling
* o2_message_send(). If the message is a bundle (you have added
* messages using o2_add_message()), do not call o2_message_finish().
* Instead, call o2_service_message_finish().
*/
o2_message_ptr o2_message_finish(o2_time time, const char *address,
int tcp_flag);
/**
* \brief finish and return a message, prepending service name
*
* @param time the timestamp for the message (0 for immediate)
* @param service a string to prepend to address or NULL.
* @param address the O2 address pattern for the message. If this
* is a bundle, address should be "" (empty string)
* @param tcp_flag boolean if true, send message reliably
*
* @return the address of the completed message, or NULL on error
*
* The message must be freed using o2_message_free() or by calling
* o2_message_send(). This function is intended to be used to
* forward OSC messages to a service, but it is the implementation
* of o2_message_finish(), which simply passes NULL for service.
*/
o2_message_ptr o2_service_message_finish(o2_time time,
const char *service, const char *address, int tcp_flag);
/**
* \brief free a message allocated by o2_send_start().
*
* This function is not normally used because O2 functions that send
* messages take "ownership" of messages and (eventually) free them.
*/
void o2_message_free(o2_message_ptr msg);
/**
* \brief send a message allocated by o2_send_start().
*
* This is similar to calling o2_send(), except you use a three-step
* process of (1) allocate the message with o2_send_start(), (2) add
* parameters to it using `o2_add_` functions, and (3) call
* o2_send_finish() to send it.
*
* @param time the timestamp for the message
* @param address the destination address including the service name.
* To send a bundle to a service named foo, use the
* address "#foo"
* @param tcp_flag boolean that says to send the message reliably.
* Normally, true means use TCP, and false means use UDP.
*
* @return #O2_SUCCESS if success, #O2_FAIL if not.
*/
int o2_send_finish(o2_time time, const char *address, int tcp_flag);
/** @} */
/**
* \defgroup lowlevelparse Low-Level Message Parsing
*
* These functions can retrieve message arguments one-at-a-time.
* There are some hidden state variables to keep track of the state
* of unpacking, so these functions are not reentrant.
* Arguments are returned using a pointer to a union type: #o2_arg_ptr.
*
*/
/** \addtogroup lowlevelparse
* @{
*/
/**
* \brief initialize internal state to parse, extract, and coerce
* message arguments.
*
* @return length of the type string in msg
*
* To get arguments from a message, call o2_extract_start(), then for
* each parameter, call o2_get_next().
*/
int o2_extract_start(o2_msg_data_ptr msg);
/**
* \brief get the next message parameter
*
* This function is called repeatedly to obtain parameters in order
* from the message passed to o2_extract_start().
*
* If the message parameter type matches the `type_code`, a pointer to
* the parameter is returned. If the types do not match, but coercion
* is possible, the parameter is coerced, copied to a new location,
* and a pointer is returned. Otherwise, NULL is returned.
*
* The type of any non-NULL return value always matches the type
* specified by the parameter `type_code`. To determine the
* original type of the parameter as specified by the message, use the
* `types` string which is passed to message handlers. (Or course,
* this assumes that message type strings are correct. Badly formed
* messages are detected when the type string and data imply that the
* message is longer than the actual length, but otherwise there is no
* way to detect errors in type strings.)
*
* The result points into the message or to a statically allocated
* buffer if type coercion is required. This storage is valid
* until the next call to `o2_extract_start`. If the value is a
* pointer (string, symbol, midi data, blob), then the value was
* not copied and remains in place within the message, so there should
* never be the need to immediately copy the data pointed to.
* However, since the storage for the value is the message, and
* the message will be freed when the handler returns,
* pointers to strings, symbols, midi data, and blobs
* *must not* be used after the handler returns.
*
### Example 1: Simple but not completely robust
Note: call o2_method_new() with type_spec = "id", h = my_handler,
coerce = false, parse = false. In this case, since there is
no type coercion, type_spec must match the message exactly,
so o2_get_next() should always return a non-null o2_arg_ptr.
However, this code can fail if a badly formed message is sent
because there is no test for the NULL value that will be
returned by o2_get_next().
\code{.c}
int my_handler(o2_message_ptr msg, char *types,
o2_arg_ptr *argv, int argc, void *user_data)
{
o2_extract_start(msg);
// we expect an int32 and a double argument
int32_t my_int = o2_get_next(O2_INT32)->i32;
double my_double = o2_get_next(O2_DOUBLE)->d;
...
}
\endcode
### Example 2: Type coercion and type checking.
Note: call o2_method_new() with type_spec = NULL, h = my_handler,
coerce = false, parse = false. In this case, even though
coerce is false, there is no type_spec, so the handler will
be called without type checking. We could check the
actual message types (given by types), but here, we will
coerce into our desired types (int32 and double) if possible.
Since type coercion can fail (e.g. string will not be converted
to number, not even "123"), we need to check the return value
from o2_get_next(), where NULL indicates incompatible types.
\code{.c}
int my_handler(o2_message_ptr msg, char *types,
o2_arg_ptr *argv, int argc, void *user_data)
{
o2_extract_start(msg);
// we want to get an int32 and a double argument
o2_arg_ptr ap = o2_get_next(O2_INT32);
if (!ap) return O2_FAIL; // parameter cannot be coerced
int32_t my_int = ap->i32;
o2_arg_ptr ap = o2_get_next(O2_DOUBLE);
if (!ap) return O2_FAIL; // parameter cannot be coerced
double my_double = ap->d;
...
}
\endcode
*
* @param type_code the desired parameter type
*
* @return the next message parameter or NULL if no more parameters
*/
o2_arg_ptr o2_get_next(o2_type type_code);
/** @} */
/* Scheduling */
/** \addtogroup basics
* @{
*/
// Messages are stored in the table modulo their timestamp, so the
// table acts sort of like a hash table (this is also called the
// timing wheel structure). Messages are stored as linked lists sorted
// by increasing timestamps when there are collisions.
/** \cond INTERNAL */ \
// Size of scheduler table.
#define O2_SCHED_TABLE_LEN 128
// Scheduler data structure.
typedef struct o2_sched {
int64_t last_bin;
double last_time;
o2_message_ptr table[O2_SCHED_TABLE_LEN];
} o2_sched, *o2_sched_ptr;
/** \endcond */
/**
* \brief Scheduler that schedules according to global (master) clock
* time
*
* Scheduling on this scheduler (including sending timed messages)
* will only work after clock synchronization is obtained. Until then,
* timed message sends will fail and attempts to o2_schedule() will
* fail.
*/
extern o2_sched o2_gtsched;
/**
* \brief Scheduler that schedules according to local clock time
*
* It may be necessary to schedule events before clock synchronization
* with the master clock, or you may want to schedule local processing
* that ignores any changes in clock time or clock speed needed to
* stay synchronized with the master clock (even though these should
* be small). For example, O2 uses the local time scheduler to
* schedule the clock synchronization protocol, which of course must
* run before clock synchronization is obtained.
*
* In these cases, you should schedule messages using #o2_ltsched.
*/
extern o2_sched o2_ltsched;
/**
* \brief Current scheduler.
*
* When a timed message is delivered by a scheduler, #o2_active_sched
* is set to pount to the scheduler. A handler that constructs and
* schedules a message can use this pointer to continue using the same
* scheduler.
*/
extern o2_sched_ptr o2_active_sched; // the scheduler that should be used
/**
* /brief Schedule a message.
*
* Rather than sending a message, messages can be directly
* scheduled. This is particulary useful if you want to schedule
* activity before clock synchronization is achieved. For example, you
* might want to poll every second waiting for clock
* synchronization. In that case, you need to use the local scheduler
* (#o2_ltsched). o2_send() will use the global time scheduler
* (#o2_gtsched), so your only option is to construct a message and
* call o2_schedule().
*
* @param scheduler a pointer to a scheduler (`&o2_ltsched` or
* `&o2_gtsched`)
* @param msg a pointer to the message to schedule
*
* The message is scheduled for delivery according to its timestamp
* (which is interpreted as local or global time depending on the
* scheduler).
*
* The message is delivered immediately if the time is zero or less
* than the current time; however, to avoid unbounded recursion,
* messages scheduled within handlers are appended to a "pending
* messages" queue and delivered after the handler returns.
*/
int o2_schedule(o2_sched_ptr scheduler, o2_message_ptr msg);
/** @} */ // end of a basics group
#ifdef __cplusplus
}
#endif
#endif /* O2_H */
|