#include "packet.h"
-
-
static status_t destroy(packet_t *this)
{
pfree(this->data.ptr);
return SUCCESS;
}
+/**
+ * @brief helper function to set address used by set_dest & set_source
+ */
+static status_t set_addr(int family, struct sockaddr *saddr, char *address, u_int16_t port)
+{
+ switch (family)
+ {
+ /* IPv4 */
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in*)saddr;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin->sin_port = htons(port);
+ return SUCCESS;;
+ }
+ }
+ return NOT_SUPPORTED;
+}
+
+status_t set_destination(packet_t *this, char *address, u_int16_t port)
+{
+ struct sockaddr *saddr = &(this->destination);
+ return set_addr(this->family, saddr, address, port);
+}
+
+status_t set_source(packet_t *this, char *address, u_int16_t port)
+{
+ struct sockaddr *saddr = &(this->source);
+ return set_addr(this->family, saddr, address, port);
+}
+
-packet_t *packet_create()
+packet_t *packet_create(int family)
{
packet_t *this = alloc_thing(packet_t, "packet_t");
this->destroy = destroy;
-
+ this->set_destination = set_destination;
+ this->set_source = set_source;
+
+ this->family = family;
+ switch (family)
+ {
+ case AF_INET:
+ this->sockaddr_len = sizeof(struct sockaddr_in);
+ break;
+ default: /* not supported */
+ pfree(this);
+ return NULL;
+ }
+
this->data.len = 0;
this->data.ptr = NULL;
return this;
-
}
typedef struct packet_s packet_t;
struct packet_s {
/**
- * senders address and port
+ * Address family, such as AF_INET
*/
- struct {
- struct sockaddr_in addr;
- size_t len;
- } sender;
+ int family;
+ size_t sockaddr_len;
+
+ /**
+ * source address structure
+ */
+ struct sockaddr source;
/**
- * receivers address and port
+ * destination address structure
*/
- struct {
- struct sockaddr_in addr;
- size_t len;
- } receiver;
+ struct sockaddr destination;
/**
* message data
*/
chunk_t data;
+ status_t (*set_destination) (packet_t *packet, char *address, u_int16_t port);
+ status_t (*set_source) (packet_t *packet, char *address, u_int16_t port);
+
/**
* @brief
*
* @param
* @return
*/
-packet_t *packet_create();
+packet_t *packet_create(int family);
#endif /*PACKET_H_*/
{
char buffer[MAX_PACKET];
- packet_t *pkt = packet_create();
+
+ packet_t *pkt = packet_create(AF_INET);
/* do the read */
- pkt->sender.len = sizeof(pkt->sender.addr);
pkt->data.len = recvfrom(this->socket_fd, buffer, MAX_PACKET, 0,
- &(pkt->sender.addr), &(pkt->sender.len));
+ &(pkt->source), &(pkt->sockaddr_len));
+
if (pkt->data.len < 0)
{
pkt->destroy(pkt);
{
ssize_t bytes_sent;
- printf("@%d\n", __LINE__);
/* send data */
bytes_sent = sendto(this->socket_fd, packet->data.ptr, packet->data.len,
- 0, &(packet->receiver.addr), packet->receiver.len);
-
- printf("bytes: %d\n", bytes_sent);
+ 0, &(packet->destination), packet->sockaddr_len);
+
if (bytes_sent != packet->data.len)
{
+ perror("Sendto error");
return FAILED;
}
return SUCCESS;
return SUCCESS;
}
-socket_t *socket_create()
+socket_t *socket_create(u_int16_t port)
{
private_socket_t *this = alloc_thing(socket_t, "private_socket_t");
struct sockaddr_in addr;
this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
this->public.destroy = (status_t(*)(socket_t*))destroyer;
- printf("@%d\n", __LINE__);
/* create default ipv4 socket */
this->socket_fd = socket(PF_INET, SOCK_DGRAM, 0);
if (this->socket_fd < 0) {
return NULL;
}
- printf("@%d\n", __LINE__);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = 500;
+ addr.sin_port = htons(port);
if (bind(this->socket_fd,(struct sockaddr*)&addr, sizeof(addr)) < 0) {
pfree(this);
return NULL;
}
- printf("@%d\n", __LINE__);
return (socket_t*)this;
}
* @param
* @return
*/
-socket_t *socket_create();
+socket_t *socket_create(u_int16_t port);
#endif /*SOCKET_H_*/
int i;
for (i = 0; i < testinfo->insert_item_count; i++)
{
- packet_t *packet = packet_create();
+ packet_t *packet = packet_create(AF_INET);
testinfo->tester->assert_true(testinfo->tester,(packet != NULL), "create packet call check");
testinfo->tester->assert_true(testinfo->tester,(testinfo->send_queue->add(testinfo->send_queue,packet) == SUCCESS), "add packet call check");
}
*/
void test_socket(tester_t *tester)
{
- socket_t *skt = socket_create();
- packet_t *pkt = packet_create();
+ int packet_count = 5;
+ int current;
+ socket_t *skt = socket_create(4500);
+ packet_t *pkt = packet_create(AF_INET);
char *test_string = "Testing functionality of socket_t";
pkt->data.ptr = test_string;
pkt->data.len = strlen(test_string);
- pkt->receiver.addr.sin_family = AF_INET;
- pkt->receiver.addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- pkt->receiver.addr.sin_port = htons(500);
-
- skt->send(skt, pkt);
+ /* send to previously bound socket */
+ pkt->set_destination(pkt, "127.0.0.1", 4500);
+
+ /* send packet_count packets */
+ for (current = 0; current < packet_count; current++)
+ {
+ if (skt->send(skt, pkt) == FAILED)
+ {
+ tester->assert_true(tester, 0, "packet send");
+ }
+ }
pkt->destroy(pkt);
- skt->receive(skt, &pkt);
- tester->assert_false(tester, strcmp(test_string, pkt->data.ptr), "packet exchange");
+ /* receive packet_count packets */
+ for (current = 0; current < packet_count; current++)
+ {
+ skt->receive(skt, &pkt);
+ tester->assert_false(tester, strcmp(test_string, pkt->data.ptr), "packet exchange");
+ pkt->destroy(pkt);
+ }
}