1 /***************************************************************************
4 * Thu Nov 19 15:13:08 2009
5 * Copyright 2009 Marcin Miklas
6 * <marcin.miklas@teleca.com>
7 ****************************************************************************/
9 #include <netinet/in.h>
14 ServiceMessage* pack_pdu(int sigid, uns8* payload, int payload_len, int* pdu_len) {
15 /* Now we need to construct a Service Message to send to the Hello, world
16 * service at the other end. Our service message will look like this:
18 0xA1 SIGID 0x41 LENGTH DATA
19 Length of 8 bit Argument Length Data
20 signal ID sigid type of data field
22 * Ok, so what exactly does all this mean? Let's go through it one
24 * - 0xA1: this is the length of the following signal ID. 0xA1 means
25 * it will be 1 byte long (8 bits).
26 * - SIGID: Signal Identifiers are used by service nodes to recognize
27 * incoming signals (messages). A list of valid signals should be
28 * provided in the Service Interface Specification.
29 * - 0x41: Type of the following argument, or one of NULL, TRUE or
30 * FALSE for simple items where these values are enough.
31 * The bytes following the argument type field make up the value of
32 * the argument. For example, an argument type of 0x14 (unsigned 32-bit
33 * integer) is followed by 4 bytes of data, representing the integer
34 * value in question. In our case, the argument type is 0x41, which
35 * stands for binary data (in our case, the test string we will be
36 * sending). For binary data items such as strings, the argument item
37 * is further divided into two parts:
38 * - LENGTH: Length of the following binary data, in octets. This is an
39 * 8 bit value, so the maximum length is 255 octets. For longer items,
40 * use type 0x42, which has a 16-bit length field.
41 * - DATA: The amount of data specified by LENGTH.
43 * For more information about Service Messages, see Appendix D of the
44 * NoTA platform programming guide.
46 if (!payload) payload_len = 0;
47 ServiceMessage* smsg = (ServiceMessage*)malloc( SERVICE_MESSAGE_HEADER_LEN + payload_len );
48 smsg->sigid_length = 0xA1;
49 smsg->sigid[0] = sigid;
50 smsg->argtype = payload ? 0x42 : 0x01;
51 smsg->arglen = htons(payload_len);
54 memcpy(smsg->argdata, payload, payload_len);
58 *pdu_len = SERVICE_MESSAGE_HEADER_LEN + payload_len;
60 *pdu_len -= sizeof(smsg->arglen);
67 /* If we decide to discard a message before it is fully
69 * have some way of abandoning remaining data on the
71 * This function serves that purpose for the time being
72 * (that is, until HIN3 supports message-based sockets).
74 static void clear(HSSockID socket,int quiet, ServiceCallbacks* cb)
80 err = n_read(socket, &buf, 64, HSReceiveNonBlocking);
83 LOG1("%02x ", buf[i++]);
91 HErrorCode read_smsg(HSSockID* socket, HSReceiveMode mode, ServiceCallbacks* cb)
97 /* In the following lines, we will read the service message from
98 * the internal RX buffer into the 'smsg' variable. The first bytes
99 * of a NoTA service message will tell us what kind of message
100 * we're dealing with.
102 error = n_read(*socket, &smsg.sigid_length, sizeof(smsg.sigid_length), mode);
106 if (smsg.sigid_length != 0xA1)
108 //LOG("Only 8-bit signal identifiers currently recognized.\n");
109 clear(*socket, 1, cb);
112 error = n_read(*socket, &smsg.sigid, 2, mode);
116 switch(smsg.sigid[0])
120 error = n_read(*socket, &smsg.argtype, 1, mode);
123 if (smsg.argtype != 0x42)
125 clear(*socket, 0, cb);
128 error = n_read(*socket, &smsg.arglen, 2, mode);
129 smsg.arglen = ntohs(smsg.arglen);
132 uns8* argdata = malloc(smsg.arglen);
133 error = n_read(*socket, argdata, smsg.arglen, HSReceiveBlocking);
134 if (error == smsg.arglen)
137 cb->put_image(argdata,smsg.arglen);
141 LOG2("Error: got only %d bytes of %d expected.\n", error, smsg.arglen);
144 free((void*)argdata);
148 error = n_read(*socket, &smsg.argtype, 1, mode);
151 if (smsg.argtype != 0x01)
153 clear(*socket, 0, cb);
160 ServiceMessage* smsg;
164 last_img = cb->get_image(&last_img_size);
167 smsg = pack_pdu(PUT_IMAGE, last_img, last_img_size, &smsg_len);
168 error = n_send(*socket, smsg, smsg_len, HSSendBlocking);
176 error = n_read(*socket, &smsg.argtype, 1, mode);
179 if (smsg.argtype != 0x42)
181 clear(*socket, 0, cb);
184 error = n_read(*socket, &smsg.arglen, 2, mode);
185 smsg.arglen = ntohs(smsg.arglen);
189 struct {int x,y,r;} face;
190 error = n_read(*socket, &face, sizeof(face), HSReceiveBlocking);
191 if (error == smsg.arglen) {
193 cb->face_found(ntohl(face.x),ntohl(face.y),ntohl(face.r));
199 if (cb->disconnect) {
200 cb->disconnect(*socket);
211 LOG("Unsupported service call.\n");
212 clear(*socket, 0, cb);